volatile简单理解 volatile线程可见性有序性synchronized
程序员文章站
2024-02-28 21:00:58
...
习惯了先举个例子,这个是我学习时遇到的问题。
volatile x = 0;
A,B俩个线程。
都做加一操作x=x+1。
输出结果A线程X=1, B线程X=1.(一种情况)
我自己期望出现的结果:1,2。我的理解是,当A线程改变了x的值,B会及时知道,然后做加一操作,那么等到结果一定是2。可是忘了加操作和赋值是2个操作,x=x+1并非原子性。
分析:
1,A,B线程均读到x=0
2,B做加一操作,等到结果为1,由于x=x+1是非原子性操作,所以此时未赋值给x
3,A做完加一操作,主内存中x的值此时为1。
4,由于volatile确保了可见性,所以此时B更新内存x值,此时B线程中x=1。
5,加操作完后应该赋值了,把1赋给x,所以此时B线程中x=1。
最后结果输出2个1。
可以从步骤上看到,加了volatile并不会像加了synchronized一样,一个线程执行完后,另一个线程再执行,所以volatile没有确保线程的有序性。A改变x值后,B重新读取x的值,这样就如同volatile定义一样,一个线程改变了共享变量,其它线程可见,亦可见性。
与未加volatile比,B线程是不会做第4步更新x值的操作。valatile确保线程的可见性,确保当共享变量改变时,其它线程可见。
由于volatile只确保了可见性,所以用到它的地方,一般是赋值操作,确保了得到的值是最新的值。
volatile x = 0;
A,B俩个线程。
都做加一操作x=x+1。
输出结果A线程X=1, B线程X=1.(一种情况)
我自己期望出现的结果:1,2。我的理解是,当A线程改变了x的值,B会及时知道,然后做加一操作,那么等到结果一定是2。可是忘了加操作和赋值是2个操作,x=x+1并非原子性。
分析:
1,A,B线程均读到x=0
2,B做加一操作,等到结果为1,由于x=x+1是非原子性操作,所以此时未赋值给x
3,A做完加一操作,主内存中x的值此时为1。
4,由于volatile确保了可见性,所以此时B更新内存x值,此时B线程中x=1。
5,加操作完后应该赋值了,把1赋给x,所以此时B线程中x=1。
最后结果输出2个1。
可以从步骤上看到,加了volatile并不会像加了synchronized一样,一个线程执行完后,另一个线程再执行,所以volatile没有确保线程的有序性。A改变x值后,B重新读取x的值,这样就如同volatile定义一样,一个线程改变了共享变量,其它线程可见,亦可见性。
与未加volatile比,B线程是不会做第4步更新x值的操作。valatile确保线程的可见性,确保当共享变量改变时,其它线程可见。
由于volatile只确保了可见性,所以用到它的地方,一般是赋值操作,确保了得到的值是最新的值。
上一篇: 转:破解JIRA3.3 .netHTML