AAA线程拿到副本进行操作,几乎同时主线程也拿到了number的副本进行while循环,当AAA三秒
之后将number修改为60,随后写入内存中,但是此时主线程还是使用自己的内存空间中的number副
本,因此循环继续。
如果给while语句前面添加上延迟时间,保证while拿到数据的时候AAA线程已经完成了修改并写入
主内存,那么while拿到的就是number修改之后的值
2、JMM原子性
什么是原子性?其实就是看最终一致性能不能保证。不可分割、完整性。即某个线程正在做某个业
务的时候,中间不可以被加塞或者被分割,需要整体完整。
JMM要求保证原子性,但是volatile是不保证原子性的。
class MyData{
//volatile就是增强了主线程和线程的可见性
volatile int number = 0;
public void addTO60(){
this.number = 60;
}
}
/**
* 1.验证volatile的可见性
* 1.1 假如int number = 0; number变量之前没有添加volatile关键字修饰,没有可见性
*/
public class VolatileDemo {
public static void main(String[] args) {
MyData myData = new MyData();//线程操作资源类
new Thread(() -> {
System.out.println(Thread.currentThread().getName()+"\t come
in");
//线程暂停3秒钟
try { TimeUnit.SECONDS.sleep(3); }catch (Exception e)
{e.printStackTrace();}
//3秒钟以后将把0改为60
myData.addTO60();
System.out.println(Thread.currentThread().getName()+"\t updated
number value:"+myData.number);
},"AAA").start();
//第二个线程就是我们的main线程
while (myData.number == 0){
//main主线程就一直在这里等待循环,直到number不再等于零
}
//若这句话打印出来了,说明main主线程感知到了number的值发生了变化,那么此时可见
性就会被触发
System.out.println(Thread.currentThread().getName()+"\t mission is
over,main get number value:"+myData.number); //这个是main线程
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
评论0
最新资源