线程安全的实现方法,包含如下方式

一, 互斥同步

使用互斥锁的方式。

举个栗子

synchronized,最常用的同步实现方案,

ReentrantLock,java并发包中工具,后续介绍。

互斥同步的优点:

比较悲观,在共享资源抢占频繁的情况下,能很好的保护共享资源的同步使用,防止数据错误。

互斥同步的缺点:

性能较差,因线程需要阻塞等待;

线程阻塞唤醒需要用户态与核心态切换,会消耗cpu性能。

二, 非阻塞同步

顾名思义,就是通过不阻塞线程的方式进行共享资源的同步操作,具体方法有就是使用CAS思想进行并发策略,具体详情如下:

具体操作方案:

CAS设计中包含三个操作数:

读写的内存位置(V)

进行比较的预期原值(A)

拟写入的新值(B)

如果内存位置V的值与预期原值A相匹配,那么处理器会自动将该位置值更新为新值B,否则处理器不做任何操作。

当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程没有阻塞,而是进行“自旋”等待(如同想上厕所而没有便位的你)。

2.1场景:

CAS操作的乐观,是基于大部分多线程的场景,其实共享变量或资源并未频繁变动,而变动后的值,而变动后的值绝大部分时候是与变动前不一致的。

2.2 优点:

能在大部分场景中,加快并发的效率。

2.2.1 比起悲观锁频繁的阻塞或同步等待,CAS消耗更少。

2.2.2 大部分处理的情况,线程抢占到锁后执行得很快,而进去阻塞状态的线程再抢占执行和一直在cpu中执行自旋抢占,存在cpu的线程上下文切换的消耗,因此能提升效率。

2.3 缺点:

2.3.1 不适用线程抢占激烈的情况

2.3.2 ABA问题(即共享的值被其他线程修改多次,导致值从A>B>A,又与预期值一致的情况,目前已通过加版本号等手段解决)

2.3.3 只能对单个变量操作

三,无同步方案

一个方法如果不涉及共享数据,那它自然就无须任何同步措施去保证多线程的安全性。

3.1 可重入代码

多个线程访问同一个方法的局部变量时,是不会出现线程安全问题,因为局部变量存储在虚拟机栈中,属于线程私有的。如下图所示

局部变量示意图

如下代码所示,将信息通过参数传入,使用局部变量而非类变量,不依赖共享资源。

public void change(int num) {

Integer i= 0;

for (; i < num; i++) {

//do Something

}

3.2 线程本地存储(Thread Local Storage)

把共享数据的可见范围限制在同一个线程之内,无须同步来能保证线程之间不出现数据争用的问题。

ThreadLocal并不是一个Thread,而是Thread的内部变量,用于存放本线程使用的数据,仅本线程可见。

如下图所示:

ThreadLocal示意图

举个栗子:

ThreadLocal的使用方式:

public class ThreadLocalTest {

class ThreadTest extends Thread {

private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

@Override

public void run() {

for (int i = 0; i < 10; i++) {

threadLocal.set(i);

System.out.println( getName()+" threadLocal is " + threadLocal.get(i));

}

}

}

public static void main(String[] args) {

ThreadTest thread1 = new ThreadTest();

thread1.setName("thread1");

ThreadTest thread2 = new ThreadTest();

thread2.setName("thread2");

thread1.start();

thread2.start();

}

}

运行结果如下:

thread1 threadLocal is 0

thread2 threadLocal is 0

thread1 threadLocal is 1

thread2 threadLocal is 1

thread1 threadLocal is 2

thread2 threadLocal is 2

thread1 threadLocal is 3

thread2 threadLocal is 3

thread1 threadLocal is 4

thread2 threadLocal is 4

thread1 threadLocal is 5

thread2 threadLocal is 5

thread1 threadLocal is 6

thread2 threadLocal is 6

thread1 threadLocal is 7

thread2 threadLocal is 7

thread1 threadLocal is 8

thread2 threadLocal is 8

thread1 threadLocal is 9

thread2 threadLocal is 9

两个线程的内容不会冲突。

举个栗子

典型的应用场景就是 Web 应用中的“一个请求对应一个服务器线程”的处理,每个请求的内容放在线程本地变量内。

java queue 线程安全_java并发编程之线程安全方法相关推荐

  1. java线程状态_java并发编程之线程状态

    java线程中,线程状态是如何转换的呢?这一次我们一起来学习下. 线程状态: NEW: 线程创建之后,还没有启动.这时候它的状态就是NEW RUNNABLE: 正在Java虚拟机下跑任务的线程的状态. ...

  2. c++ 线程池_JAVA并发编程:线程池ThreadPoolExecutor源码分析

    前面的文章已经详细分析了线程池的工作原理及其基本应用,接下来本文将从底层源码分析一下线程池的执行过程.在看源码的时候,首先带着以下两个问题去仔细阅读.一是线程池如何保证核心线程数不会被销毁,空闲线程数 ...

  3. java线程池_Java 并发编程 线程池源码实战

    作者 | 马启航 杏仁后端工程师.「我头发还多,你们呢?」 一.概述 笔者在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写 ...

  4. java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂

    引言 通过前面的文章,我们学习了Executor框架中的核心类ThreadPoolExecutor ,对于线程池的核心调度机制有了一定的了解,并且成功使用ThreadPoolExecutor 创建了线 ...

  5. java 关闭守护线程_Java并发编程之线程生命周期、守护线程、优先级、关闭和join、sleep、yield、interrupt...

    Java并发编程中,其中一个难点是对线程生命周期的理解,和多种线程控制方法.线程沟通方法的灵活运用.这些方法和概念之间彼此联系紧密,共同构成了Java并发编程基石之一. Java线程的生命周期 Jav ...

  6. java等待5秒_Java并发编程-主线程等待子线程解决方案

    主线程等待所有子线程执行完成之后,再继续往下执行的解决方案 public class TestThread extends Thread { public void run() { System.ou ...

  7. java 共享锁 独占锁_Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家取排队本着先来 ...

  8. java中解决脏读_java并发编程学习之脏读代码示例及处理

    使用interrupt()中断线程     当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即 ...

  9. java程序使用异步总线_JAVA并发编程基础

    CPU核心 核心(Die)又称为内核,是CPU最重要的组成部分.CPU中心那块隆起的芯片就是核心,是由单晶硅以一定的生产工艺制造出来的,CPU所有的计算.接受/存储命令.处理数据都由核心执行.各种CP ...

最新文章

  1. 疫情排查节时86%?不会代码也能玩转模型训练?腾讯大神揭秘语音语义及AutoML黑科技 | 内含福利...
  2. IAR8.32.4 for ARM安装预注册教程
  3. 按钮右对齐_9张图,学会Excel中的对齐技巧
  4. Spring Boot——易班优课YOOC课群在线测试自动答题解决方案(二)答案储存
  5. python3.10_概述 — Python 3.10.0a2 文档
  6. 浅谈C++ STL中的优先队列(priority_queue)
  7. deepin如何布署python_Dlib库教程(2):联合python的人脸检测、标记、识别
  8. Java (计算机编程语言)
  9. 官方AI语音系统电销机器人系统搭建|AI智能|电话机器人源码|2022最新电销外呼系统《各版本机器人部署》
  10. c语言 opengl函数魔方,基于OpenGL的3D旋转魔方实现汇总.docx
  11. 中年危机:全面贬值的中年人
  12. 解决iText 5.0.1,加入iTextAsian.jar 出现异常 Font 'STSong-Light' with 'UniGB-UCS2-H'
  13. mysql 用idb文件恢复数据
  14. 虚拟内存技术的来龙去脉(上)
  15. WIN7 iTunes无法识别iPhone,重装系统解决
  16. 胡谨的个人简介及一生
  17. 利用melendy插入参考文献,4种方法快速插入参考文献,soo easy!
  18. 易语言C盘文件管理员权限,更改C盘文件提示需要管理员权限
  19. 动态代理最全详解系列[2]-Proxy生成代理类对象源码分析
  20. 从0到1搭建大数据平台之数据存储

热门文章

  1. 数字万用表测量二极管、三极管
  2. 从源码分析DEARGUI之键盘鼠标事件监控
  3. opencv-python图像处理之素描
  4. Netty之SimpleChannelInboundHandler
  5. 【转自聊聊架构公众号】 Redis大key图形化统计及展示
  6. 转载:Objective-C中的 instancetype 和 id 关键字
  7. mysql复习增删改查
  8. IOS开发中的变量、方法、属性
  9. 30天敏捷结果(5):使用热图标识出重要事情
  10. Python中使用librosa包进行mfcc特征参数提取