0%

volatile关键字

要了解volatile则需要了解java的工作内存和主内存之间的关系


在java的内存模型中,每一个线程在对变量执行的所有操作都必须在工作内存中进行,工作内存中的变量则是主内存的副本拷贝。

也就是说在多个线程对一个变量进行操作的时候,因为每次操作的都是工作内存,所以在工作内存写入主内存的时,会出现数据不一致的现象。

volatile关键字

volatile关键字所修饰的对象不会保留拷贝,所有的操作都是直接对于主内存中的变量进行操作。

volatile只是在工作内存和主内存之间同步某个变量的值。不论在任何线程中修改了变量,其他线程能够立即得到修改后的结果。

简单数据类型声明为volatile,对它们的操作就会变成原子级别的。

但是下面这个例子则不是原子级别的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test {
volatile int n = 0;

@Test
public void test() throws InterruptedException {
Thread[] threads = new Thread[1000];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
n++;
}
});
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}

for (Thread thread : threads) {
thread.join();
System.out.println(" n= " + n);
}
}
}

打印出来的n并非都是1000

因为n++不是原子操作,同样换成n+1也是一样的结果。

只有当变量的值和自身上一个值无关时对该变量的操作才是原子级别的,如n = m + 1