-
可见的原理查看全部
-
两条规定查看全部
-
JMM查看全部
-
JMM查看全部
-
JMM查看全部
-
什么是可见性查看全部
-
long和double都是8字节64位的,当程序中有一个long或double类型的变量,而且该变量也没有任何关键字修饰,那么此时对64位的long、double变量的读写就不是原子操作,即可以分解. 因为java内存模型允许JVM将没有被volatile修饰的64位数据类型的读写操作划分为两次32位的读写操作来进行.就可能导致多线程并发访问该变量时,出现只读了一半就被抢走资源进而导致数据异常的问题. 解决方法是在long、double类型的变量上加入volatile关键字. 也可以直接使用synchronized修饰. 不过大部分虚拟机已经把long、double类型的变量对其进行一些保护,因此在实际编程中也不需刻意为long、double类型的数据加上volatile关键字.查看全部
-
synchronized和volatile实现内存可见性比较 volatile不需要加锁,比synchronized更轻量级,不会阻塞线程,执行效率更高. synchronized既能保证可见性,又能保证原子性,而volatile只能保证可见性,无法保证原子性.查看全部
-
要在多线程中安全的使用volatile变量,必须同时满足: 1.对变量的写入操作不依赖于其当前值 即改变后的volatile变量的值不能与它之前的值有关系. 2.该变量没有包含在具有其他变量的不变式中. 即不能存在通过volatile变量进行逻辑判断.查看全部
-
while(Thread.activeCount() > 1 ){ Thread.yield(); } //如果还有子线程在运行,主线程就让出cpu资源,直到所有的子线程都运行完了,主线程再继承往下执行.查看全部
-
volatile不能保证共享变量的原子性. number++不是原子操作,当该变量被volatile关键字修饰,在多线程并发访问时,仍然会出现共享数据异常的问题.查看全部
-
volatile实现可见性查看全部
-
volatile关键字能够保证变量的可见性 不能保证volatile变量操作的原子性,即仍然会出现当多线程并发访问时出现共享数据异常的问题. volatile是通过内存屏障和禁止重排序优化来实现的. 对volatile变量执行写操作时,会在写操作后加入一条store屏障指令. (会把当前修改后的值更新到主内存中) 对volatile变量执行读操作时,会在读操作前加入一条load屏障指令. (会从主内存中读取变量的最新值)查看全部
-
导致共享变量在线程间不可见的原因: 1.线程的交叉执行. (通过synchronized解决) 2.重排序结合线程交叉执行 (通过synchronized解决) 3.共享变量更新后的值没有在工作内存与主内存间及时更新 (synchronized或volatile) 共享变量不可见就会导致数据异常. synchronized可以保证共享变量可见性与程序执行的原子性查看全部
-
as-if-serial语义 as-if-serial:无论如何重排序,程序执行的结果应该与代码顺序执行的结果一致. Java保证单线程下遵循as-if-serial语义. 重排序不会给单线程带来内存可见性问题.因为保证as-if-serial语义. 多线程中程序交错执行时,重排序可能会造成内存可见性问题. 多线程中程序交错执行时,本身就会导致内存可见性问题而导致数据异常. 若多线程中线程不交叉执行,则相当于单线程的状态,重排序也不会导致内存可见性问题.查看全部
举报
0/150
提交
取消