volatile的作用
简单描述下,根据JMM(java内存模型)譬如有两个线程,并发执行的时候,除去公用的堆内存(主内存)外,有自己的本地内存,在线程被激活时,会从主内存拷贝变量到本地内存,进行操作,操作完成某个时间会将变量再拷贝回去主内存,这样如果有多个线程,可能多个线程分别保留了一个副本,这样是线程不安全的,此时需要加上volatile关键字,这个关键字的作用在于,每次让线程读取这个变量的时候,都必须从主内存来读,并且如果有一个线程获取了这个变量到本线程的本地内存的时候,主内存的变量不可读取,这样就避免了数据不一致,以下代码演示加不加volatile关键字的区别
file: ThreadTest.java public class ThreadTest extends Thread{ private int count = 0; public int getCount() { return count; } public void setCount(int count) { this.count = count; } public void run() { for (;;) { System.out.println(count); count++; try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } file: Main.java public class Main { public static void main(String[] args) throws InterruptedException { ThreadTest tt = new ThreadTest(); tt.start(); for (;;) { if (tt.getCount() == 10) { tt.setCount(20); }} }
此时由于没有加volatile关键字,在主线程我修改了count为20,但并没有反映到线程tt上,tt上打印的count还是10、11
而当我给count变量加上了volatile关键字时,主线程的set方法会修改主内存的count变量,同时tt线程取count值的时候会从主内存取而不是本地内存取,因此保持了两个线程数据的一致性