java – 使用volatile和synchronized时,刷新或发布到各种线程的
这个问题仅涉及内存可见性,不会发生在之前和发生之后.
Java中有四种方法可以保证一个线程中的内存更改对另一个线程可见. (参考
http://gee.cs.oswego.edu/dl/cpj/jmm.html)
>写入线程释放同步锁,读取线程随后获取相同的同步锁. 根据Java Concurrency in Practice,关于这些问题的圣经:
挥发性的问题 这是否意味着JVM实际上跟踪了易失性变量读写,以便知道如何将内存从A刷新到B而不是A到C?所以A写入变量,后来C从变量读取,然后B从变量读取,刷新是在A和B以及A和C之间的每个线程基础上完成的,而不是B和C?或者,它是否暗示所有缓存的内存都被刷新,无论线程如何?只是刷新了volatile变量,还是所有缓存的内存? 同步问题 对于synchronized关键字刷新,它表示只有锁内部更新的内存才能保证发布到其他线程.这意味着在下面的代码中,两个运行method()的线程,保留synchronized块会将staticVar2刷新到另一个线程,但不是staticVar1,这是正确的吗? 此外,在method2()中,如果另一个线程正在执行method(),则可以导致在发生问题之前发生 – 遇到问题.但是,问题在于可见性.如果线程A执行方法,那么后来的线程B执行method2(),是从A到B发布的staticVar2的值,即使这两个线程没有通过同一个锁同步? static int staticVar1,staticVar2; void method() { staticVar1++; synchronized (lock) { staticVar2++; } } void method2() { synchronized (differentLock) { staticVar2++; } } 静态问题 在我看来,如果staticVar1永远不会更新到其他线程,那么任何程序中的所有静态变量都需要一个volatile声明,或者只能在synchronized块中访问.这似乎相当苛刻,但它是否正确?我确定在我的时间里看到了很多不同步的静态变量. 综上所述 >易失性读写会将所有内存刷新到所有线程,还是仅在两个访问线程之间?无论哪个答案,是所有内存都刷新了还是只有易变量? 解决方法
内存方面没有范围限制.当您具有读或写屏障时,它适用于所有内存读/写.
我在哪里看到了内存映射的限制.当你的内存映射文件时,你必须要小心如何使这个可用于另一个线程,因为这个新的内存映射可能在另一个线程中不可见,立即导致BUS错误(以及JVM崩溃)这似乎是一个操作系统错误,因为最新版本的Linux和Windows似乎没有这个问题.
当staticVar2可能更快时,statixVar1将始终被刷新.不保证何时,但订单有保证.
是的,使用的锁对于先发生的保证无关紧要.
所有脏内存都在写屏障上刷新,所有读取在读屏障上都是顺序一致的. volatile执行写操作时的写屏障和读操作时的读屏障.
该线程改变了所有内存.
仅当一个线程修改变量时.任何数量的线程都可以读取静态值而无需同步. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |