volatile关键字要求线程在使用变量的时候,必须立刻从主内存读取,在修改完成以后,立刻将数据写入主内存。
这个过程没法对线程进行同步。
好比:
线程1从主内存读取到count的值为2,尚未操做的时候,线程2从主内存也把count读取到线程内部,这个时候依然是2.
而后线程1把count自加1设为3,当即刷新到主内存里面。线程2也把counter自加1设置为3,刷新到主内存里面
这样,线程2的操做就丢失了。
java
所以能够使用加锁或者AtomicInteger关键字来处理ide
public class VolatileWrong { volatile static int count = 0; public static void main(String[] args) { new VolatileWrong().new ThreadHandler().start(); new VolatileWrong().new ThreadHandler().start(); new VolatileWrong().new ThreadHandler().start(); new VolatileWrong().new ThreadHandler().start(); try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count); } class ThreadHandler extends Thread { @Override public void run() { for(int i = 0; i< 10000; i++){ count++; } } } }
===============================================this
import java.util.concurrent.CountDownLatch; public class VolatileWrong1 { volatile static int count = 0; public static void main(String[] args) { CountDownLatch cdl = new CountDownLatch(4); new VolatileWrong1().new ThreadHandler(cdl).start(); new VolatileWrong1().new ThreadHandler(cdl).start(); new VolatileWrong1().new ThreadHandler(cdl).start(); new VolatileWrong1().new ThreadHandler(cdl).start(); try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count); } class ThreadHandler extends Thread { CountDownLatch cdl ; ThreadHandler(CountDownLatch cdl){ this.cdl = cdl; } @Override public void run() { for(int i = 0; i< 1000000; i++){ count++; } cdl.countDown(); } } }
==============应使用以下代码==========================atom
import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; public class VolatileWrong2 { static AtomicInteger count = new AtomicInteger(0) ; public static void main(String[] args) { CountDownLatch cdl = new CountDownLatch(4); new VolatileWrong2().new ThreadHandler(cdl).start(); new VolatileWrong2().new ThreadHandler(cdl).start(); new VolatileWrong2().new ThreadHandler(cdl).start(); new VolatileWrong2().new ThreadHandler(cdl).start(); try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count); } class ThreadHandler extends Thread { CountDownLatch cdl ; ThreadHandler(CountDownLatch cdl){ this.cdl = cdl; } @Override public void run() { for(int i = 0; i< 1000000; i++){ count.incrementAndGet(); //count.getAndIncrement(); } cdl.countDown(); } } }