2.3.6原子类也并不安全

原子类在具有有逻辑性的情况下输出结果也具有随机性

/**
 * @author wuyoushan
 * @date 2017/4/19.
 */
public class MyService {
    public static AtomicLong atomicLong=new AtomicLong();

    public void addNum(){
        System.out.println(Thread.currentThread().getName()+"加了100之后的值是:"
        +atomicLong.addAndGet(100));
        atomicLong.addAndGet(1);
    }
}

/**
 * MyThread线程测试
 * @author wuyoushan
 * @date 2017/3/21.
 */
public class MyThread extends Thread {

    private MyService myService;

    public MyThread(MyService myService) {
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        super.run();
        myService.addNum();
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
      try{
            MyService service=new MyService();
            MyThread[] array=new MyThread[5];
          for (int i = 0; i < array.length; i++) {
              array[i]=new MyThread(service);
          }

          for (int i = 0; i < array.length; i++) {
              array[i].start();
          }
          Thread.sleep(1000);
          System.out.println(service.atomicLong.get());
      }catch (InterruptedException e){
            e.printStackTrace();
      }
    }
}

程序的运行结果为:

Thread-2加了100之后的值是:100
Thread-3加了100之后的值是:201
Thread-4加了100之后的值是:502
Thread-0加了100之后的值是:401
Thread-1加了100之后的值是:301
505

打印顺序出错了,应该是每加1次100再加1次1.出现这样的情况是因为addAndGet()方法是原子的,但方法和方法之间的调用却不是原子的。解决这样的问题必须要同步。

更改MyService.java文件代码如下:

/**
 * @author wuyoushan
 * @date 2017/4/19.
 */
public class MyService {
    public static AtomicLong atomicLong=new AtomicLong();

    synchronized public void addNum(){
        System.out.println(Thread.currentThread().getName()+"加了100之后的值是:"
        +atomicLong.addAndGet(100));
        atomicLong.addAndGet(1);
    }
}

程序的运行结果为:

Thread-0加了100之后的值是:100
Thread-1加了100之后的值是:201
Thread-2加了100之后的值是:302
Thread-3加了100之后的值是:403
Thread-4加了100之后的值是:504
505

从运行的结果可以看到,是每次加100再加1,这就是我们想要得到的过程,结果505的同时还保证在过程中的累加的顺序也是正确的。

摘选自 java多线程核心编程技术-2.3.6

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,500评论 19 139
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,747评论 11 349
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 34,612评论 18 399
  • Softly sighs the rainbow. Misty songs of all. Flowing by ...
    岛歌在跑阅读 607评论 0 2
  • 今天上了一节实验课,让自己在课堂中不喊、不生气、与学生共同上体育课的实验。感觉真的很好,这一节课上的太棒了...
    醉酒笑看人生阅读 243评论 0 4

友情链接更多精彩内容