沐风Cc 2020-07-27 13:52 采纳率: 100%
浏览 820
已采纳

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

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条回答 默认 最新

  • 毋丶疗 2020-07-27 14:39
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • bobhuang 2020-07-27 14:36
    关注

    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条)

报告相同问题?

悬赏问题

  • ¥20 C语言字符串不区分大小写字典排序相关问题
  • ¥15 关于#python#的问题:我希望通过逆向技术爬取1688搜索页下滑加载的数据
  • ¥15 学习C++过程中遇到的问题
  • ¥15 关于Linux的终端里,模拟实现一个带口令保护的屏保程序遇到的输入输出的问题!(语言-c语言)
  • ¥15 学习C++过程中遇到的问题
  • ¥15 请问,这个嵌入式Linux系统怎么分析,crc检验区域在哪
  • ¥15 二分类改为多分类问题
  • ¥15 Unity微信小游戏上调用ReadPixels()方法报错
  • ¥15 如何通过求后验分布求得样本中属于两种物种其中一种的概率?
  • ¥15 q从常量变成sin函数,怎么改写python代码?