请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于100有没有可能不会打印出来的问题

new Thread(new Runnable() {
	@Override
    public void run() {
	    while (count < 100) {
		    synchronized (lock) {
	            if ((count & 1) == 0) {
	                System.out.println(Thread.currentThread().getName() + ":" + count++);
                }
            }
        }
    }
}, "偶数");

这是视频里打印偶数的线程代码。

这里while的条件是count < 100,注意到结果中出现了偶数:100,也就是说在count == 99时,该线程已经进入了while代码块。
有没有一种可能,偶数线程自打印完98后,再也没有被CPU调度,直到奇数线程打印完99后(此时count已经是100)才再次获取CPU,从而无法打印出100

如果存在这种可能,那这段代码就是依赖于执行环境的。记得在哪里看过一句话好像是说,不应该对CPU的速度和数量做任何假设。

刚才跑了一个测试,发现确实有很小的概率出现打印不出来100的情况。

正在回答 回答被采纳积分+3

2回答

这是代码的问题,两个线程都可能满足 while(count < 100) ,然后其中 1 个被卡在 synchronized 里,if 判断是否奇偶数的时候,再次判断一遍 count 条件就行 ,不过我这里用的 <= 

附调整后的代码参考:

 public class ThreadPrintNumQuestionOne {

    public static int count = 0;

    public static Object lock = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            while (count <= 100) {
                synchronized (lock) {
                    if (count <= 100 && (count & 1) == 0) {
                        System.out.println(Thread.currentThread().getName() + " 偶数:" + count++);
                    }
                }
            }
        }).start();

        new Thread(() -> {
            while (count <= 100) {
                synchronized (lock) {
                    if (count <= 100 && (count & 1) == 1) {
                        System.out.println(Thread.currentThread().getName() + " 奇数:" + count++);
                    }
                }
            }
        }).start();
    }

}

那么这样方案的缺点也会更多,1:多次判断 count ,效率低,2:当前奇/偶线程不满足本身该处理的数据的时候,要一直重复进行锁竞争,抢到锁的线程也不一定是满足打印数字的线程,效率更是大大折扣。

0 回复 有任何疑惑可以回复我~
  • 悟空 #1
    恩,这种方案虽然有缺点,不过更准确。
    回复 有任何疑惑可以回复我~ 2022-11-05 11:08:26
悟空 2021-11-27 22:01:36

谢谢小伙伴的提醒,我觉得你说得对,这里确实存在很小的概率是你说的情况。

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号