两个线程交替打印


public class PrintABVolatile implements IPrintAB {
    private static final int MAX_PRINT_NUM = 100;
    private static volatile int count = 0;
​
    @Override
    public void printAB() {
        new Thread(() -> {
            while (count < MAX_PRINT_NUM) {
                if (count % 2 == 0) {
                    log.info("num:" + count);
                    count++;
                }
            }
        }).start();
​
        new Thread(() -> {
            while (count < MAX_PRINT_NUM) {
                if (count % 2 == 1) {
                    log.info("num:" + count);
                    count++;
                }
            }
        }).start();
    }
}

请问这样能保证线程安全吗..感觉volatile不能保证啊 i++不是原子的

阅读 3.8k
5 个回答

incrementAndGet()底层是CAS操作,调用的是Unsafe类,线程安全

答案你自己已经说了..

我觉得是没有问题的

首先volatile是有可见性的,就是一个线程修改了count,其他线程也可以获取count的最新值
两个线程内部都是循环执行的,如果count%2==0,那么线程一可以打印,那么线程二会一直循环,当count++之后,线程二回获取到count值,并执行打印。
为什么会有i++原子性问题呢?
当然,我对线程也是一知半解,如果有错误欢迎指出错误

新手上路,请多包涵

count++本身确实有原子性问题,但是volatile修饰后,可以认为两个线程同时看到的count的值是相同的,这样的话,关键点就是两个while循环里的if条件,是互斥的,也就是说,count在同一时刻只能满足其中一个if的条件,而另外一个if不满足,就只能一直循环,等满足条件的if执行完修改了count的值之后再进入,这样就实现了交替

有问题,问题在于count < MAX_PRINT_NUM / count % 2 这两个判断不是连续原子的,可能导致MAX_PRINT_NUM依然被输出

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题