求大佬解答一下关于两个线程交替打印奇偶数的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bee7
V2EX    Java

求大佬解答一下关于两个线程交替打印奇偶数的问题

  •  
  •   bee7 2020-07-23 14:04:09 +08:00 2749 次点击
    这是一个创建于 1924 天前的主题,其中的信息可能已经有所发展或是发生改变。

    就是下面的代码是交替打印 0 到 100 的奇偶数,我这里的循环条件是 count 小于 100,为什么最后的输出结果会一直到 100 呢,不是 100 就跳出循环执行不到了吗,求大佬解答

    public class WaitNotifyPrintOddEvenSyn { private static int count; private static final Object lock = new Object(); //建 2 个线程,一个只处理偶数,一个只处理奇数 //并且用 synchronized 来通信 public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { while(count < 100){ synchronized (lock){ if((count & 1) == 0){ System.out.println(Thread.currentThread().getName() + ": " + count); count++; } } } } }, "偶线程").start(); new Thread(new Runnable() { @Override public void run() { while(count < 100){ synchronized (lock){ if((count & 1) == 1){ System.out.println(Thread.currentThread().getName() + ": " + count); count++; } } } } }, "奇线程").start(); } } 
    9 条回复    2020-07-29 16:23:34 +08:00
    popesaga
        1
    popesaga  
       2020-07-23 14:11:20 +08:00   2
    count++ 不是原子操作,再了解一下 volatile 和 AtomicInteger 。一个线程在做 count < 100 判断的时候读到了 99,然后才有另外一个线程的 count++ 引起的新值 100 更新的操作,再接着一个释放锁一个获得锁,100 就会被打印出来。
    sonice
        2
    sonice  
       2020-07-23 14:12:23 +08:00
    用 AtomicInteger
    araraloren
        3
    araraloren  
       2020-07-23 14:13:14 +08:00
    count 是 99 的时候可能让两个线程同时通过 while 条件。。
    bee7
        4
    bee7  
    OP
       2020-07-23 14:14:16 +08:00
    @popesaga 感谢大佬,懂了!!
    JasonLaw
        5
    JasonLaw  
       2020-07-23 15:07:54 +08:00   1
    @popesaga #1
    @bee7 #4

    count++本身不是原子操作,但是代码里已经使用了内置锁保证了 count++的原子性。根本问题不是 count++,而是没有用锁保护好 count 这个共享可变变量,也就是两个线程可以“同时”执行 count < 100 判断。如果当前 count 是 99,奇线程执行判断成功,获取锁,但是在更新 count 值之前,这个时候奇线程中止了,轮到偶线程执行,虽然判断成功,但是没办法获取锁,不过等到奇线程释放锁之后,偶线程就可以获取到锁了,最后偶线程会打印出 100 。
    eve1yb0dy
        6
    eve1yb0dy  
       2020-07-23 16:36:11 +08:00
    我关注楼主名字...起的有意思
    kkkkkrua
        7
    kkkkkrua  
       2020-07-23 16:38:07 +08:00
    这写法不过关啊,看看 Reentrantlock
    M1NGc
        8
    M1NGc  
       2020-07-24 15:45:05 +08:00
    用同步队列
    Octopvs
        9
    Octopvs  
       2020-07-29 16:23:34 +08:00
    用双重检查锁就可以,sync 前判断一次<100,sync 后再判断一次就好了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1203 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 23:36 PVG 07:36 LAX 16:36 JFK 19:36
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86