AtomicInteger 关键字保证线程共享变量线程安全

线程安全:

当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用代码代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的。

线程共享:

当某个资源需要被多个线程同时访问时,该资源就是一个线程共享的资源,这时就需要注意这个变量是否线程安全,会不会因为多个线程的访问而导致值发送不符合预期的改变。

synchronized(保证同一时刻只有获得锁的线程才能访问,其他线程被阻塞)

Java提供了强制性的内置锁机制:synchronized块。一个synchronized块有两个部分:锁对象的引用,以及这个锁保护的代码块。执行线程进入synchronized块之前会自动获得锁,无论通过正常控制路径退出还是从块中抛出异常,线程都在放弃对synchronized块的控制时自动释放锁。获得内部锁的唯一途径是:进入这个内部锁保护的同步块或方法。 
内部锁在Java中扮演了互斥锁的角色,意味着至多只有一个线程可以拥有锁。

volatile(保证线程的可见性)

violate关键字对于自增操作无法保证线程安全,自增操作本身并不是原子操作;例如count = count +1;violatile并不能保证原子性

我们知道,volatile关键字不能用来做计数器,因为它只能保证两个特性:
1.可见性(对volatile变量所有的写操作都能立即反应到其他线程中,换句话说,volatile变量在各个线程中是一致的(得益于java内存模型—"先行发生原则",任何线程对被violatile关键字修饰的变量的操作,都是直接反应到主存上,其他线程读取时也是从贮存读取,能保证一定能读到最新值))
2.禁止指令重排序

ThreadLocal(各个线程维护自己的一个副本,互相隔离)

ThreadLocal不是一个线程的本地实现版本,它不是一个Thread,而是线程布局变量,为每一个使用该变量的线程都提供了一个变量值的副本。 
  从线程的角度看,每一个线程都保持一个对其线程局部变量副本的隐式引用,只要线程时活动的并且ThreadLocal实例是可访问的。 
  JVM为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境出现的并发问题提供了一种隔离机制。这种隔离机制与同步机制不同,同步机制才用了“以时间换空间”的方式,而ThreadLocal才用了“以空间换时间”的方式,前者仅提供一份变量,让不同的线程排队访问,后者则为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

 

AtomicInteger(实现线程共享变量)

可用做多线程的计数器,比如有一个线程共享变量,要保证多个线程对这个计数器进行累加。

原帖:https://blog.csdn.net/fanrenxiang/article/details/80623884

我们知道,阻塞同步和非阻塞同步都是实现线程安全的两个保障手段,

阻塞同步:Sychonize是阻塞同步的一种实现

非阻塞同步:

对于阻塞同步而言主要解决了阻塞同步中线程阻塞和唤醒带来的性能问题,那什么叫做非阻塞同步呢?在并发环境下,某个线程对共享变量先进行操作,如果没有其他线程争用共享数据那操作就成功;如果存在数据的争用冲突,那就才去补偿措施,比如不断的重试机制,直到成功为止,因为这种乐观的并发策略不需要把线程挂起,也就把这种同步操作称为非阻塞同步(操作和冲突检测具备原子性)。在硬件指令集的发展驱动下,使得 "操作和冲突检测" 这种看起来需要多次操作的行为只需要一条处理器指令便可以完成,这些指令中就包括非常著名的CAS指令(Compare-And-Swap比较并交换),乐观锁的一种经典实现方式就是CAS,另一种是版本号

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值