zoukankan      html  css  js  c++  java
  • 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.4 将类内联化
    2.3 提炼类
    2.2 搬移字段
    2.1 搬移函数
    1.8 替换你的算法
    1.7 以函数对象取代函数
    1.7 移除对参数的赋值动作
    1.6 分解临时变量
    1.5 引入解释性变量
    1.4 以查询取代临时变量
  • 原文地址:https://www.cnblogs.com/edison20161121/p/8011216.html
Copyright © 2011-2022 走看看