volatile关键字
volatile 关键字是java提供的一种轻量级同步机制。他能够保证可见性和有序性,但是不能保证原子性。
volatile可见性
可见性表示被这个关键字所修饰的实例,在被修改后,其他的线程均可见。
class MyData {
volatile int number
= 0;
}
public class VolatileLookDemo {
public static void main(String
[] args
) {
MyData myData
= new MyData();
new Thread(() -> {
try {
TimeUnit
.SECONDS
.sleep(2);
myData
.number
= 100;
System
.out
.println(myData
.number
+"修改数据");
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}, "AAA").start();
new Thread(() -> {
System
.out
.println("进入了BBB的线程");
while (myData
.number
== 0) {
}
System
.out
.println("它发现number被修改为"+myData
.number
);
System
.out
.println("BBB线程要出来了");
}, "BBB").start();
}
}
代码说明:
在MyData类中我们定义了我们定义了number 域。我们可以选择添加volatile和不加volatile关键字的方式进行测试。
在主线程中我们创建了MyData的实例对象myData。我们新建了两个线程AAA与线程BBB。
我们可以看到AAA线程对myData的number进行修改。BBB线程负责监听numner是否被修改。
运行结果说明:
在number不添加volatile关键字的情况下,我们会发现我们的程序会陷入死循环。原因是:BBB线程监听number,而number在AAA线程中被修改这个事情,BBB线程他并不知道。也就是锁number在AAA线程中的操作是其他线程不可见的,所以while就会一直循环。
在number添加了volatile关键字的情况下,程序会运行结束。因为此时的number在AAA线程中的修改结果对于其他线程是可见的,那么BBB线程的while监听到number被修改为100,自然跳出了循环。
总结:
通过上面的小demo我们可以清晰的发现添加了volatile关键字后,我们的域在不同线程中的操作都是可见的。