java多线程中如何保证变量的可见性、原子性

原创 2018年04月15日 19:24:53

做过多线程开发的猿友们应该会遇到这两个问题

首先,理解一下可见性:

线程在修改主存变量的时候会先拷贝一份到自己的线程栈中去处理,每个线程都有自己的空间,相互是独立的,在变量修改完成到写入主存中,这个过程对其它线程是不可见的。(这里不明白的话可以看一下java内存模型及线程间的通信)

那么问题来了 不可见会如何?数据的一致性会被打乱,程序出bug,A线程改了变量c的值,B线程读到的却是c原来的值(其实想要的是A线程改后的值)

解决办法:

使用synchronized(低效,使用悲观锁)、volatile修饰符来保证变量的可见性

Jdk5后提出了atomic 原子操作也可以保证可见性(高效且不需要使用同步,基于CAS)

Volatilesynchronized区别

Volatile只是保证变量可见性,并不能确保原子性,它是依赖CPU提供的特殊指令内存屏障指令来控制可见性,被Volatile修饰的成员变量在被线程访问时在读操作前会强行插入一条内存屏障读指令强行从主存中读取(让高速缓存中的数据失效,重新从主内存加载数据),变量在被线程修改时会在写指令之后插入写屏障让写入缓存的最新数据写回到主内存

不能确保原子性,是因为如果A线程和B线程同时读取到变量a值,A线程修改a后将值刷到主存、同时B线程也修改了a的值并刷到主存,这时候B线程就覆盖了A线程修改操作。

Synchronized是通过对线程加锁(独占锁)控制线程同步,被Synchronized修饰的内存只允许一个线程访问

Cas理解(乐观锁基于CAS

3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做,重新再尝试。注意ABA情况



java多线程之共享变量的可见性、原子性

1.概述: 提到多线程,就不可避免地涉及到数据争用的问题。这包括了多线程对共享变量的可见性和原子性操作;(共享变量:如果一个变量在多个线程的工作内存(工作内存:每个线程都有自己的工作内存)中都存在副...
  • yaonga
  • yaonga
  • 2017年05月26日 09:33
  • 719

Java关键字volatile,原子性,变量可见性

内存模型与CPU缓存 本来CPU计算的数字都是从主从main memory中读取的,但是CPU运行的速度比计算机读取内存的速度快,为了补齐这个短板,所以出现了CPU缓从这种东西。 在多CPU...
  • Matthewhou
  • Matthewhou
  • 2017年07月20日 14:49
  • 418

Java并发编程--原子性和可见性

原子性竞态条件:当某个计算的正确性取决于多个线程的交替执行时序时,那么就会发生竞态条件。常见的竞态条件类型是先检查后执行操作,即通过一个可能失效的观测结果来决定下一步的动作。要避免竞态条件问题,就必须...
  • wujingjing_crystal
  • wujingjing_crystal
  • 2016年05月14日 15:34
  • 971

为什么volatile不能保证原子性而Atomic可以(valatile只保证可见性,不保证原子性)

在上篇《非阻塞同步算法与CAS(Compare and Swap)无锁算法》中讲到在Java中long赋值不是原子操作,因为先写32位,再写后32位,分两步操作,而AtomicLong赋值是原子操作,...
  • zhanghongzheng3213
  • zhanghongzheng3213
  • 2016年07月25日 17:54
  • 1641

Java多线程中提到的原子性和可见性、有序性

原子性 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。如果一个操作时原子性的,那么多线程并发的情况下,就不会出现变量被修改的情况比如 a=0...
  • jaryle
  • jaryle
  • 2016年05月18日 10:56
  • 6885

volatile 可以保证可见性,但不能保证原子性

转自:http://blog.csdn.net/shukebai/article/details/51163068 在Java线程并发处理中,有一个关键字volatile的使用目前存...
  • u010791823
  • u010791823
  • 2017年03月28日 21:50
  • 338

Java多线程 之 原子性与可见性(八)

1.原子性java中的原子性,是指:原子操作是不能被线程调度机制中断的;操作一旦开始,它一定会在可能发生的“上下文切换”(即切换到其他线程执行)之前执行完毕。 但是千万不要认为“原子操作不需要同步控...
  • fan2012huan
  • fan2012huan
  • 2016年06月19日 19:00
  • 1835

Java同步——可见性和原子性

参考文章:http://www.cnblogs.com/Mainz/p/3556430.html#
  • u012973218
  • u012973218
  • 2016年05月05日 11:29
  • 453

并发编程(原子性、可见性、一致性)

1、原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。如果一个操作时原子性的,那么多线程并发的情况下,就不会出现...
  • zhaxiaodong
  • zhaxiaodong
  • 2017年12月18日 16:47
  • 197

java并发之原子性、可见性、有序性

原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,...
  • gongpulin
  • gongpulin
  • 2016年04月21日 18:30
  • 1824
收藏助手
不良信息举报
您举报文章:java多线程中如何保证变量的可见性、原子性
举报原因:
原因补充:

(最多只允许输入30个字)