猿问

java Synchronized 内存可见性问题

java中的Synchronized有2个作用

1. 互斥访问

2. 保证内存可见性

关于第二点,总是有点疑惑,看了很多资料,一般这么描述,

1. 在同一个锁上修改,读取共享变量,读线程总是可以获取最新变量值。

2. 后面又有 这样的描述: 线程释放锁时会将强制刷新工作内存中的脏数据到主内存中,获取一个锁将强制线程装载(或重新装载)字段的值.

这里有个链接 http://ifeve.com/syn-jmm-visibility/

这样我也有点困惑,以前没仔细想清楚,特地写了以下代码,希望高手可以解惑。

假设有3个线程,线程1先调用set方法,然后线程2调用get方法,线程3调用get2方法


则可以肯定线程2可以看到线程1修改的num值,

线程3是否肯定可以看到最新值呢?


蛊毒传说
浏览 680回答 2
2回答

波斯汪

线程3可以看到最新值,java会对锁住的对象判断是否处于竞争中,如果没有被竞争,那么会立即执行。如果三个线程是并发执行,那种情况就不确定了,线程2都不一定是最新值,因为有可能线程1还未执行。如果线程1先执行,那么lock1就已经被释放了,那么此时lock1和lock2就都是处于未被锁住的情况,即不存在锁竞争关系,线程2 、3同时执行必然能取到最新值,不然java的多线程会出现不可预估的数据错误,后果很严重。锁的意义是防止线程竞争造成共享数据混乱,有竞争就会让线程排队等候,其实就是把同时执行的情况改造成类似同步的顺序执行,Synchronized这个词的意思就是“同步”,其本质就是让线程的异步变为同步

SMILET

描述里只是说明synchronized开始时刷新一次和退出时提交一次,但并不表示代码块在执行的过程中,不会提交或刷新共享变量,所以情况分很多种,纠结这种问题没什么意义.你可以在set()方法里写一个循环对num进行累加,在get2()里多次获取,看看锁未释放时,num是不是不变的.
随时随地看视频慕课网APP
我要回答