关于100有没有可能不会打印出来的问题
来源:7-7 交替打印

Super丶Lee
2021-11-27
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的情况。
写回答
2回答
-
花草木香丶忆花间相见
2022-11-03
这是代码的问题,两个线程都可能满足 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:当前奇/偶线程不满足本身该处理的数据的时候,要一直重复进行锁竞争,抢到锁的线程也不一定是满足打印数字的线程,效率更是大大折扣。
012022-11-05 -
悟空
2021-11-27
谢谢小伙伴的提醒,我觉得你说得对,这里确实存在很小的概率是你说的情况。
00
相似问题