[英]How to make sure two threads printing even odd numbers maintain even first then odd order for this implementation?
[英]About two threads alternately printing odd and even numbers
也就是说,下面的代码交替打印从 0 到 100 的奇数和偶数。 我的循环条件是计数小于 100。
为什么最终的 output 结果达到 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();
}
}
这发生在变量count
的值为99
时。
考虑两个有趣的场景:
count
的值为 99。
现在两个线程都通过了第一个过滤器,即if(count < 100)
。
现在两个线程都将竞相获取变量lock
。
让first thread = A
和second thread = B
。
场景1:如果A胜过B :
然后 if 条件if((count & 1) == 0)
将失败,因为count
是奇数。
线程 A 没有打印任何内容,A 释放锁,B 获取锁。
现在,B 打印值 99 并将count
的值增加到 100。
情景1是预料之中的!
但是,可能存在场景 2。
场景 2:如果B战胜A并且 A 必须等待 B 完成:
count
的值为 99。
现在两个线程都通过了第一个过滤器,即if(count < 100)
。
在这种情况下,if 条件if((count & 1) == 1)
被传递为count
是奇数。
B 打印值 99 并将count
的值增加到 100。
现在,A 中的 if 条件if((count & 1) == 0)
也将通过,因为count
的值是偶数,即 100。
因此,线程 A 打印 100。
那么现在,如何解决这个问题呢?
回答:
只需在线程 A 的 if 条件中引入一个条件来检查 if count<100
。
if((count & 1) == 0 && count<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 && count<100){
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();
}
}
Output:
偶线程: 0
奇线程: 1
偶线程: 2
奇线程: 3
偶线程: 4
奇线程: 5
偶线程: 6
奇线程: 7
偶线程: 8
奇线程: 9
偶线程: 10
奇线程: 11
偶线程: 12
奇线程: 13
偶线程: 14
奇线程: 15
偶线程: 16
奇线程: 17
偶线程: 18
奇线程: 19
偶线程: 20
奇线程: 21
偶线程: 22
奇线程: 23
偶线程: 24
奇线程: 25
偶线程: 26
奇线程: 27
偶线程: 28
奇线程: 29
偶线程: 30
奇线程: 31
偶线程: 32
奇线程: 33
偶线程: 34
奇线程: 35
偶线程: 36
奇线程: 37
偶线程: 38
奇线程: 39
偶线程: 40
奇线程: 41
偶线程: 42
奇线程: 43
偶线程: 44
奇线程: 45
偶线程: 46
奇线程: 47
偶线程: 48
奇线程: 49
偶线程: 50
奇线程: 51
偶线程: 52
奇线程: 53
偶线程: 54
奇线程: 55
偶线程: 56
奇线程: 57
偶线程: 58
奇线程: 59
偶线程: 60
奇线程: 61
偶线程: 62
奇线程: 63
偶线程: 64
奇线程: 65
偶线程: 66
奇线程: 67
偶线程: 68
奇线程: 69
偶线程: 70
奇线程: 71
偶线程: 72
奇线程: 73
偶线程: 74
奇线程: 75
偶线程: 76
奇线程: 77
偶线程: 78
奇线程: 79
偶线程: 80
奇线程: 81
偶线程: 82
奇线程: 83
偶线程: 84
奇线程: 85
偶线程: 86
奇线程: 87
偶线程: 88
奇线程: 89
偶线程: 90
奇线程: 91
偶线程: 92
奇线程: 93
偶线程: 94
奇线程: 95
偶线程: 96
奇线程: 97
偶线程: 98
奇线程: 99
PS:我还建议您查看并研究wait()
和notify()
方法,并编写逻辑上更健壮的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.