【问题标题】:How can I use wait/notify to make these threads work alternatively?如何使用等待/通知使这些线程交替工作?
【发布时间】:2020-08-25 19:55:06
【问题描述】:

我想了解如何让两个线程在正确的时间互相挂起,我尝试查看文档和其他内容,但理解不够;我想做一个像这样的程序:

ThreadA 一次在 ThreadB 中写入一个 int 作为属性,然后 B 打印它。 A 等待写另一个 int,直到它从 B 确认打印了前一个,并且 B 必须等待 A 在打印之前写了 int

如果我使用A/B.suspend()A/B.resume() 情况会更清楚,但我不明白如何使用waitnotify 做同样的事情。

这是我所做的一个示例(不起作用):

public class Main {
    public static void main(String[] args) {
        Object lock=new Object();
        ThreadB tB=new ThreadB(lock);
        tB.start();
        ThreadA tA=new ThreadA(lock);
        tA.start();
    }
}

线程A:

public class ThreadA extends Thread {
    private Object lock;
    private ThreadB threadB;
    public ThreadA(Object b,ThreadB tb) {
        lock=b;
        threadB=tb;
    }
    public void run() {
        for(int i=0;i<10;i++) {
                threadB.setI(i);
                synchronized(lock) { //(try/catch omitted for shortness)
                    lock.notify();  //to tell B the int was loaded
                    lock.wait();    //to stop until B tells me that the int has been used
                }   
        }
        //join or something for B
    }   
}

线程 B:


public class ThreadB extends Thread {
    private Object lock;
    int i;
    public ThreadB(Object b) {
        lock=b;
    }
    public void setI(int x) {
        i=x;
    }
    public void run() {
        while(true) {
            synchronized(lock) { //(try/catch omitted for shortness)
                lock.wait();    //to wait until A loaded the int
            }
            int a=i;
            System.out.println(a);
            synchronized(lock) {
                lock.notify();  //to tell A it can load the next int    
            }
        }
    }   
}

我正在考虑使用lock 作为令牌,但我认为这还不够,例如,A 可能会为 B 调用 notify,然后 B 继续通知 A,但 A 甚至没有等待还是……

【问题讨论】:

  • 您应该使用类似于实际锁的东西。您可能应该使用 notifyAll 而不是 notify。此外,可能会发生虚假唤醒,因此您需要在释放时实际恢复,而不仅仅是在通知“等待”时恢复。 ReentrantLock 可能是您要找的东西?另外,您对比赛条件的看法是正确的。

标签: java multithreading wait notify


【解决方案1】:

您可以考虑使用共享标志来决定每个线程何时可以访问该变量。 请参阅此示例:processor.java 每个方法(生产和消费)都在自己的线程中独立执行(参见app.java)。

他们使用列表的大小来决定他们是否可以访问列表。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多