mufeng633
沐风Cc
采纳率62.5%
2020-07-27 13:52

AtomicInteger原子类,这种情况下为什么线程不安全?

5
已采纳

AtomicInteger是原子类,线程应该是安全的,为什么这种情况下,导致了线程不安全?

class MyThread111 implements Runnable{

    AtomicInteger count = new AtomicInteger(10);

    @Override
    public void run() {
        count.decrementAndGet();
        System.out.println("线程" +Thread.currentThread().getName() + "购票成功,剩余:" + count);
    }

    public static void main(String[] args) {
        MyThread111 myThread1 = new MyThread111();
        Thread thread = new Thread(myThread1);
        Thread thread2 = new Thread(myThread1);
        Thread thread3 = new Thread(myThread1);
        thread.start();
        thread2.start();
        thread3.start();
    }
}

运行结果:

线程Thread-0购票成功,剩余:8
线程Thread-2购票成功,剩余:7
线程Thread-1购票成功,剩余:8

期望值是:

线程Thread-0购票成功,剩余:8
线程Thread-2购票成功,剩余:7
线程Thread-1购票成功,剩余:9

为什么运行的结果是线程不安全的呢? AtomicInteger是线程安全的啊

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • qq9746 毋丶疗 8月前

    原子类的方法也都是原子性的,但是不能保证多个方法连续调用是原子性的,这里先自减再打印,结合在一起不能保证线程安全,还是要加锁或者再定义一个变量去接收自减操作后的值,再打印这个变量的值。
    比如上述状况,就是 线程0 先走了自减,还没来得及打印,线程1就进行自减操作,这时候线程0打印的时候获取的count就是 8

    点赞 评论 复制链接分享
  • bobhuang bobhuang 8月前

    count.decrementAndGet(); 时的count,跟println时已经不一样了。

    public class MyThread111 implements Runnable{
    
        AtomicInteger count = new AtomicInteger(10);
    
        @Override
        public void run() {
            int cur_count = count.decrementAndGet();
            System.out.println("线程" +Thread.currentThread().getName() + "购票成功,剩余:" + cur_count);
        }
    
        public static void main(String[] args) {
            MyThread111 myThread1 = new MyThread111();
            Thread thread = new Thread(myThread1);
            Thread thread2 = new Thread(myThread1);
            Thread thread3 = new Thread(myThread1);
            thread.start();
            thread2.start();
            thread3.start();
        }
    }
    
    
    点赞 1 评论 复制链接分享

为你推荐