Volatile关键字
说明
因为线程访问相同资源都是先复制到自己的内存空间,使用后将结果回写到公共空间。这是导致多个线程访问相同资源时会出现同一个资源被其它线程修改后另外的线程依然没有知晓。这时需要使用volatile关键字进行修饰。
测试
public class Person {
volatile int age = 10;
public void addAge() {
age++;
}
}
public class VolatileTest {
public static void main(String[] args) {
Person person = new Person();
new Thread(() -> {
System.out.println("线程A开始" + "age:" + person.age);
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
person.addAge();
System.out.println("线程A结束" + "age:" + person.age);
}, "A").start();
for (; person.age == 10; ) {
}
System.out.println("主线程结束");
}
}
这里将Person类的volatile关键字去掉运行程序将会导致程序一直处于死循环状态。因为线程A和主线程都是将主内存数据复制到自己的内存空间进行操作。A线程修改的是自己内存空间的数据,修改完成后将新的数据回写到主内存中,但是主线程并不知道person的值已经修改依然操作者拷贝副本的值,所以会一直处于自旋状态。
输出结果为:
线程A开始age:10
线程A结束age:11
加上volatile关键字后程序正常。
输出结果为:
线程A开始age:10
线程A结束age:11
主线程结束