首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用两个线程生成奇偶数通过等待通知?

使用两个线程生成奇偶数通过等待通知?
EN

Stack Overflow用户
提问于 2022-01-20 13:46:19
回答 1查看 51关注 0票数 0

我试图生成奇偶数使用2个线程通过等待通知。但它只是打印0。

有人能解释一下为什么会这样吗。

下面是我的代码:

代码语言:javascript
复制
package waitNotify2;

class Odd implements Runnable {

    Object lock;
    volatile Integer ai;

    public Odd(Object lock, Integer ai) {
        super();
        this.lock = lock;
        this.ai = ai;
    }

    @Override
    public void run() {
        synchronized(lock) {
            while(true) {
                while(ai % 2 == 0) {
                    try {
                        lock.wait();
                    } catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(ai + " ");
                ai++;
                lock.notify();
            }
        }
    }

}

class Even implements Runnable {

    Object lock;
    volatile Integer ai;

    public Even(Object lock, Integer ai) {
        super();
        this.lock = lock;
        this.ai = ai;
    }

    @Override
    public void run() {
        synchronized(lock) {
            while(true) {
                while(ai % 2 == 1) {
                    try {
                        lock.wait();
                    } catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(ai + " ");
                ai++;
                lock.notify();
            }
        }
    }

}

public class PrintOddEven2 {

    // Driver Code
    public static void main(String[] args) {
        Object o = new Object();
        Integer i = 0;
        Odd odd = new Odd(o,i);
        Even even = new Even(o,i);
        Thread t1 = new Thread(odd);

        Thread t2 = new Thread(even);
        t1.start();
        t2.start();
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-01 18:40:16

我试图生成奇偶数使用2个线程通过等待通知。但它只是打印0。有人能解释一下为什么会这样吗。

您的问题是,这两个线程都在递增ai,但它们没有共享相同的变量。因此,当偶数线程发出0并通知lock时,奇怪的线程会醒来,但它的ai副本仍然是0,所以它会回到休眠状态。

解决这个问题的一种方法是传入一个AtomicInteger,而不是Integer类。然后,当Even线程执行ai.incrementAndGet()Odd线程执行ai.get()时,它将看到对ai的更改。

如果不想使用该类,则需要编写一个MutableInteger类,如果您希望它们共享相同的变量。

其他几点评论:

  • 您的lock字段应该是final。实际上,如果可能的话,所有字段都应该是最终的,但是对于线程程序来说,final作为一条规则是很重要的。
  • 您可以将OddEven作为同一个类编写,并传递ai.get() % 2的期望值。
  • 构造函数中有一个隐含的super();,因此可以删除它。惟一需要显式指定它的时间是基类中是否有多个构造函数。
  • 当您捕获InterruptedException时,您应该在总是重新中断线程中使用Trread.currentThread().interrupt()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70787349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档