标签:原子类 something 优先 appdata oid min 允许 color 动作
1、引入话题-发散思考
2、volatile深度解析
3、解决volatile原子性问题
4、volatile应用场景
public class T1 { /*volatile*/ boolean running=true; public void m(){ System.out.println(Thread.currentThread().getName()+":start!"); while(running){ /*try { TimeUnit.MINUTES.sleep(2); } catch (Exception e) { e.printStackTrace(); }*/ } System.out.println(Thread.currentThread().getName()+":end!"); } public static void main(String[] args) { T1 t=new T1(); new Thread(()->t.m(),"t").start(); try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace(); } t.running=false; } } 运行结果: 无volatile: t:start! 有volatile: t:start! t:end!
int a=1; int b =3; int c=a*b;
//线程1: context = loadContext(); //语句1 inited = true; //语句2 //线程2: while(!inited ){ sleep() } doSomethingwithconfig(context);
1、volatile能解决原子性问题吗?什么是原子性呢,本不想解释,为了读者能够更透彻理解,再解释一下。
public class T2 { volatile int count=0; public void m(){ for(int i=0;i<1000;i++) count++; } public static void main(String[] args) { T2 t=new T2(); List<Thread> threads=new ArrayList<Thread>(); for(int i=0;i<10;i++){ threads.add(new Thread(()->t.m(),"thread-"+i)); } threads.forEach((o)->o.start()); //等待所有线程都执行完 threads.forEach((o)->o.yield()); System.out.println("count:"+t.count); } } 运行结果: count:8710 //每次都不一样。
2、为什么加了volatile还是不能得到预期结果呢?因为它只保证了可见性,不能保证原子性。what?
再回忆java内存模型:
3、那怎么解决呢?
方式一:synchronized,jvm对synchronized进行了很大的优化,所以效率也没有想象中那么低。
public class T3 { int count=0; public synchronized void m(){ for(int i=0;i<1000;i++) count++; } public static void main(String[] args) { T3 t=new T3(); List<Thread> threads=new ArrayList<Thread>(); for(int i=0;i<10;i++){ threads.add(new Thread(()->t.m(),"thread-"+i)); } threads.forEach((o)->o.start()); //等待所有线程都执行完 threads.forEach((o)->o.yield()); System.out.println("count:"+t.count); } }
方式二:ReentrantLock,跟synchronized的作用差不多。
public class T5 { ReentrantLock lock=new ReentrantLock(); int count=0; public void m(){ lock.lock(); for(int i=0;i<1000;i++) count++; lock.unlock(); } public static void main(String[] args) { T4 t=new T4(); List<Thread> threads=new ArrayList<Thread>(); for(int i=0;i<10;i++){ threads.add(new Thread(()->t.m(),"thread-"+i)); } threads.forEach((o)->o.start()); //等待所有线程都执行完 threads.forEach((o)->o.yield()); System.out.println("count:"+t.count); } }
public class T4 { AtomicInteger count=new AtomicInteger(0); public void m(){ for(int i=0;i<1000;i++) count.getAndIncrement(); } public static void main(String[] args) { T4 t=new T4(); List<Thread> threads=new ArrayList<Thread>(); for(int i=0;i<10;i++){ threads.add(new Thread(()->t.m(),"thread-"+i)); } threads.forEach((o)->o.start()); //等待所有线程都执行完 threads.forEach((o)->o.yield()); System.out.println("count:"+t.count); } }
volatile boolean inited = false; //线程1: context = loadContext(); inited = true; //线程2: while(!inited ){ sleep() } doSomethingwithconfig(context);
作者:邱勇Aaron
出处:http://www.cnblogs.com/qiuyong/
您的支持是对博主深入思考总结的最大鼓励。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,尊重作者的劳动成果。
参考:深入理解JVM、马士兵并发编程、并发编程实践
volatile关键字解析:http://www.importnew.com/18126.html
标签:原子类 something 优先 appdata oid min 允许 color 动作
原文地址:http://www.cnblogs.com/qiuyong/p/7071601.html