关于volatile在并发编程中的实际作用
原因:并发编程中,由于cpu在主内存中运行的,而线程是在工作内存中执行,线程中修改共享变量的值修改的是工作内存中的变量,需要重新写入主内存中,其他线程才能够读取修改后的共享变量。
关于并发编程中的三个概念:
原子性,可见性,有序性。
valatile修饰的变量可以让代码块具备可见性和有序性,但是不具备原子性,线程中只有最简单单一的读写操作才具备原子性,如果同时具备读写修改则不具备原子性。
valatile用途:
用来判断线程的执行标志,修饰单例模式的单例类对象,进行double check。
valatile无原子性的解决办法:
synchronize:
public class Test { public int inc = 0; public synchronized void increase() { inc++; } public static void main(String[] args) { final Test test = new Test(); for(int i=0;i<10;i++){ new Thread(){ public void run() { for(int j=0;j<1000;j++) test.increase(); }; }.start(); } while(Thread.activeCount()>1) //保证前面的线程都执行完 Thread.yield(); System.out.println(test.inc); } }
lock:
public class Test { public int inc = 0; Lock lock = new ReentrantLock(); public void increase() { lock.lock(); try { inc++; } finally{ lock.unlock(); } } public static void main(String[] args) { final Test test = new Test(); for(int i=0;i<10;i++){ new Thread(){ public void run() { for(int j=0;j<1000;j++) test.increase(); }; }.start(); } while(Thread.activeCount()>1) //保证前面的线程都执行完 Thread.yield(); System.out.println(test.inc); } }
AtomicInteger:
public class Test { public AtomicInteger inc = new AtomicInteger(); public void increase() { inc.getAndIncrement(); } public static void main(String[] args) { final Test test = new Test(); for(int i=0;i<10;i++){ new Thread(){ public void run() { for(int j=0;j<1000;j++) test.increase(); }; }.start(); } while(Thread.activeCount()>1) //保证前面的线程都执行完 Thread.yield(); System.out.println(test.inc); } }

浙公网安备 33010602011771号