2.3.6原子类也并不完全安全
Posted 成功的路上总是离不开贵人的帮助,名师的指点和小人的刺激。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.3.6原子类也并不完全安全相关的知识,希望对你有一定的参考价值。
原子类在具有逻辑的情况下输出结果也具有随机性
package com.cky.thread; import java.util.concurrent.atomic.AtomicLong; /** * Created by edison on 2017/12/9. */ public class MyService { public static AtomicLong ai= new AtomicLong(); public void addNum() { System.out.println(Thread.currentThread().getName() +" 加了100之后的值是"+ ai.getAndAdd(100)); ai.getAndAdd(1); } }
package com.cky.thread; /** * Created by edison on 2017/12/9. */ public class MyThread extends Thread{ private MyService service; public MyThread(MyService service) { this.service =service; } @Override public void run() { super.run(); service.addNum(); } }
package com.cky.test; import com.cky.thread.MyService; import com.cky.thread.MyThread; /** * Created by edison on 2017/12/9. */ public class Run { public static void main(String[] args) { try { MyService myService = new MyService(); MyThread[] myThreads = new MyThread[5]; for (int i = 0; i < myThreads.length; i++) { myThreads[i] = new MyThread(myService); } for (int i = 0; i < myThreads.length; i++) { myThreads[i].start(); } Thread.sleep(1000); System.out.println(myService.ai.get()); } catch (InterruptedException e) { e.printStackTrace(); } } }
Thread-1 加了100之后的值是0 Thread-4 加了100之后的值是400 Thread-2 加了100之后的值是300 Thread-3 加了100之后的值是200 Thread-0 加了100之后的值是100 505
结果分析:
打印顺序出错了,应该每次加100在加一次1,出现这样的情况原因是addAndGet()方法是原子的,但方法和方法直接的调用却不是原子的
解决方案同步
package com.cky.thread; import java.util.concurrent.atomic.AtomicLong; /** * Created by edison on 2017/12/9. */ public class MyService { public static AtomicLong ai= new AtomicLong(); synchronized public void addNum() { System.out.println(Thread.currentThread().getName() +" 加了100之后的值是"+ ai.getAndAdd(100)); ai.getAndAdd(1); } }
Thread-1 加了100之后的值是0 Thread-3 加了100之后的值是101 Thread-4 加了100之后的值是202 Thread-0 加了100之后的值是303 Thread-2 加了100之后的值是404 505
以上是关于2.3.6原子类也并不完全安全的主要内容,如果未能解决你的问题,请参考以下文章