简体   繁体   English

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

[英]About two threads alternately printing odd and even numbers

That is, the following code prints odd and even numbers from 0 to 100 alternately.也就是说,下面的代码交替打印从 0 到 100 的奇数和偶数。 My loop condition is that count is less than 100.我的循环条件是计数小于 100。

Why does the final output result reach 100?为什么最终的 output 结果达到 100? If it's not 100, it can't be executed after jumping out of the loop.如果不是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();
    }
}

This occurred when the value of variable count was 99 .这发生在变量count的值为99时。

Consider the 2 interesting scenarios:考虑两个有趣的场景:

The value of count is 99. count的值为 99。

Now both threads passed the first filter, that is if(count < 100) .现在两个线程都通过了第一个过滤器,即if(count < 100)

Now both threads will race to acquire lock on variable lock .现在两个线程都将竞相获取变量lock

Let first thread = A and second thread = B .first thread = Asecond thread = B

Scenario 1: If A wins over B :场景1:如果A胜过B

Then the if condition if((count & 1) == 0) will fail because, count is odd.然后 if 条件if((count & 1) == 0)将失败,因为count是奇数。

Nothing gets printed from thread A and A releases the lock and B acquires the lock.线程 A 没有打印任何内容,A 释放锁,B 获取锁。

Now, B prints value 99 and increment the value of count to 100.现在,B 打印值 99 并将count的值增加到 100。

Scenario 1 was expected!情景1是预料之中的!

But, there can be a scenario 2.但是,可能存在场景 2。

Scenario 2: If B wins over A and A has to wait for B to get completed:场景 2:如果B战胜A并且 A 必须等待 B 完成:

The value of count is 99. count的值为 99。

Now both threads passed the first filter, that is if(count < 100) .现在两个线程都通过了第一个过滤器,即if(count < 100)

In this case, the if condition, if((count & 1) == 1) get passed as count is odd.在这种情况下,if 条件if((count & 1) == 1)被传递为count是奇数。

B prints the value 99 and increment the value of count to 100. B 打印值 99 并将count的值增加到 100。

Now, the if condition in A, if((count & 1) == 0) will also pass, as value of count is even, that is, 100.现在,A 中的 if 条件if((count & 1) == 0)也将通过,因为count的值是偶数,即 100。

So, thread A prints 100.因此,线程 A 打印 100。

So now, how to solve this problem?那么现在,如何解决这个问题呢?

Answer:回答:

Simply by just introducing a single condition in if condition of thread A to check if count<100 .只需在线程 A 的 if 条件中引入一个条件来检查 if count<100

if((count & 1) == 0 && count<100) . if((count & 1) == 0 && count<100)

Have a look at the following implementation:看看下面的实现:

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: 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: I would also suggest you to have a look at and study the wait() and notify() methods and write a more logically robust code. PS:我还建议您查看并研究wait()notify()方法,并编写逻辑上更健壮的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何确保两个线程打印偶数为偶数,对于此实现,它先保持偶数然后是奇数? - How to make sure two threads printing even odd numbers maintain even first then odd order for this implementation? java:使用2个线程打印奇数 - java: Printing odd even numbers using 2 threads 在 Java 中使用两个线程打印偶数和奇数 - Printing Even and Odd using two Threads in Java 使用两个线程打印偶数和奇数 - Printing even and odd number using two threads 当使用2个不同的线程打印奇数偶数时,animalMonitorException - illegalMonitorException while printing odd even numbers using 2 different threads 没有获得用于打印具有不同线程的偶数和奇数的desried输出 - Not getting desried output for printing even and odd numbers with different threads 使用两个线程依次使用自定义锁打印号码,其中一个正在打印,而另一个正在打印奇数 - Using custom lock print number in sequence using two threads where one is printing even other is printing odd numbers 使用两个线程顺序打印奇偶数 - Printing Odd Even number sequentially using two threads 创建两个线程,一个显示奇数,另一个显示偶数 - Create two threads, one display odd & other even numbers 在java中使用两个线程有​​效地打印奇数和偶数? - print odd and even numbers using two threads in java efficiently?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM