-
volatile: 能够保证volatile变量的可见性 不能保证volatile变量复合操作的原子性 原理: 通过加入内存屏障和进制指令重排序优化来实现的 对volatile变量执行写操作时,会在写操作后加入一条store屏障指令,强制将变量刷新到主内存中去,还能够防止编译器将volatile前面的变量重排序到后面去 对volatile变量执行读操作时,会在读操作前加入一条load屏障指令 一共8条指令 任何时刻,不同线程总能看到volatile变量的最新值查看全部
-
A当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。 B当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。 D当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。查看全部
-
加入关键字Synchronized 1.数据依赖关系才可以禁止重排序;即使是控制依赖关系也不可以禁止重排序; 2.共享变量的不可见造成线程不安全 3.共享变量不可见的原因: 线程的交叉执行; 重排序结合线程交叉执行; 共享变量更新后的值没有在工作内存和主内存中及时更新,未及时更新 4.synchronized解决不可见的方案: 原子性--由于锁的关系,线程之间不允许交叉执行 原子性+as-if-serial语义--线程不能交叉执行,重排序对于单线程不能影响运行结果 可见性--共享变量的更新执行查看全部
-
2.1和2.2存在控制依赖关系,但是任然可能重排序,先执行2.2在执行2.1 只有有数据依赖关系的时候,才会禁止指令重排序 int mid = number * 3; if (ready) { result = mid; } 导致共享变量在线程间不可见的原因: synchronized解决方案: 1、线程的交叉执行 ->原子性,加锁后同一时间只能有一条线程执行 2、重排序结果线程交叉执行 ->原子性,只有一条线程,满足as-if-serial,无论怎样重排序,结果不变 3、共享变量更新后的值没有在工作内存与主内存间及时更新 ->可见性查看全部
-
ai-if-serial查看全部
-
as-if-serial查看全部
-
重排序查看全部
-
重排序查看全部
-
线程执行互斥代码的过程查看全部
-
指令重排序: 代码书写的顺序与实际执行的顺序不同,执行重排序是编译器或处理器未来提高程序性能而作的优化 主要有3种: 1、编译器优化的重排序(编译器优化) 2、指令级并行重排序(处理器优化) 3、内存系统的重排序(处理器优化) 处理器对读写缓存进行的优化 as-if-serial: 无论如何重排序,程序执行结果应该与代码顺序执行的结果一致(java编译器、运行时和处理器都会保证java在单线程下遵循as-if-serial语义) 重排序不会给单线程带来内存可见性问题 多线程中程序交错执行时,重排序可能会造成内存可见性问题查看全部
-
synchronized实现可见性查看全部
-
要实现可见性:必须保证两点: 1、线程修改后的共享变量值能够及时从工作内存刷新到主内存中 2、其他线程能够及时把共享变量的最新值从主内存更新到自己的工作内存中 java 语言层面 支持的可见性实现方式: synchronized 原子性(同步) 可见性 两条规定: 1、线程解锁前,必须把共享变量的最新值刷新到主内存中 2、线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值 (注意:加锁和解锁需要是同一把锁) 线程解锁前对共享变量的修改在下次加锁时对其他线程可见 volatile查看全部
-
可见性查看全部
-
线程中:所有的变量都存储在主内存中 线程对共享变量的所有操作都必须在自己的工作内存中进行 通过synchronized和volatile都可以实现可见性查看全部
-
共享变量可见性实现的原理: 线程1对共享变量的修改要想被线程2及时看到,必须经过如下2个步骤: 把工作内存1中更新过的共享变量刷新到主内存中 将主内存中最新的共享变量的值更新到工作内存2中 所以这两个步骤中,任何一个有误,都是导致不可见,变量值的不准确,使线程不安全查看全部
举报
0/150
提交
取消