java线程内存刷新,java – 使用volatile和synchronized时,刷新或发布到各种线程的内存范围是什么?...

这个问题仅涉及内存可见性,不会发生在之前和发生之后.

Java中有四种方法可以保证一个线程中的内存更改对另一个线程可见. (参考

http://gee.cs.oswego.edu/dl/cpj/jmm.html)

>写入线程释放同步锁,读取线程随后获取相同的同步锁.

>如果一个字段被声明为volatile,则在写入程序线程执行任何进一步的内存操作之前,写入该文件的任何值都会被刷新并使其可见(即,为了手头的目的,它会立即刷新).

>线程第一次访问对象的字段时,它会看到字段的初始值或自某个其他线程写入的值.

>当一个线程终止时,所有写入的变量都被刷新到主存储器.

根据Java Concurrency in Practice,关于这些问题的圣经:

The visibility effects of volatile variables extend beyond the value of the volatile variable itself. When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after readin the volatile variable.

挥发性的问题

这是否意味着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块中访问.这似乎相当苛刻,但它是否正确?我确定在我的时间里看到了很多不同步的静态变量.

综上所述

>易失性读写会将所有内存刷新到所有线程,还是仅在两个访问线程之间?无论哪个答案,是所有内存都刷新了还是只有易变量?

>退出同步块时,或者只是块内更改的内存,是否刷新了内存?如果没有刷新所有内存,则线程同步的锁定对象是否必须相同才能看到该值(即锁定对象是否对内存可见性有任何影响)?

>是否必须同步两个线程访问的所有静态变量?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值