繁体   English   中英

大约两个线程交替打印奇数和偶数

[英]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 = Asecond 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM