wait() 和 notify() 相关问题

wait() and notify() related issue

我只想使用线程打印出 1 到 10。但是我的代码将在数字 1 处停止。input() 将提供从 1 到 10 的变量,而 output() 将打印出它们。 input() 将首先执行,然后执行 output()。之后 for() 将确保他们将开始另一次迭代。

class InputOutput{
    private static int i=0;
    private static boolean ToF=false;

    synchronized void output(){
        try{
            while(!ToF){
                notify();
                wait();
            }
        }
            catch(InterruptedException e){
                e.printStackTrace();
            }
        System.out.println("Output: "+i);
        ToF=false;
        notify();
    }
    synchronized void input(){
        try{
            while(ToF){
                notify();
                wait();
            }
        }
            catch(InterruptedException e){
                e.printStackTrace();
            }
        i++;
        ToF=true;
        notify();
    }
    class input implements Runnable{
    private int i=1;
    InputOutput io=new InputOutput();
    public void run(){
        for(i=1;i<=10;i++)
            io.input();
    }
    }
    class output implements Runnable{
    private int i=1;
    InputOutput io=new InputOutput();
    public void run(){
        for(i=1;i<=10;i++)
            io.output();
    }
    }
    public class Homework07Part3 {

    public static void main(String[] args) {
        Thread t1=new Thread(new input());
        t1.start();
        Thread t2=new Thread(new output());
        t2.start();
    }
}

while 循环你在一个对象上等待两个线程通信

while(ToF){
           //dont put notify here.
            notify();
            wait();
        }

使其成为实例变量

private static boolean ToF=false;

public class Homework07Part3 {

    public static void main(String[] args) {
        InputOutput io = new InputOutput();
        Thread t1 = new Thread(new input(io));
        t1.start();
        Thread t2 = new Thread(new output(io));
        t2.start();
    }

    private static class input implements Runnable {
        private int i = 1;
        private InputOutput io;

        public input(InputOutput io) {
            this.io = io;
        }

        public void run() {
            for (i = 1; i <= 10; i++)
                io.input();
        }
    }

    private static class output implements Runnable {
        private int i = 1;
        private InputOutput io;

        public output(InputOutput io) {
            this.io = io;
        }

        public void run() {
            for (i = 1; i <= 10; i++)
                io.output();
        }
    }
}

class InputOutput {
    private int i = 0;
    private boolean ToF = false;

    synchronized void output() {
        try {
            while (!ToF) {
                wait();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Output: " + i);
        ToF = false;
        notify();
    }

    synchronized void input() {
        try {
            while (ToF) {
                wait();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        i++;
        ToF = true;
        notify();
    }

}

I simply want to use thread to print out from 1 to 10. But my code will stop at number 1.

[[ 另一个答案似乎已经解决了您的问题,但它没有解释 发生了什么 以及修复工作的原因。 ]]

您的问题是两个线程都在 不同的 对象上调用 synchronizenotify() 以及 wait()。当线程使用这些信号进行通信时,它们都需要共享同一个对象实例。您正在创建 2 个 InputOutput 对象,因此您的两个线程都卡在 wait() 中,因为 notify() 调用丢失了。

class Input implements Runnable{
    ...
    // this is local to the Input class
    InputOutput io=new InputOutput();
...
class Output implements Runnable{
    ...
    // this is a different instance 
    InputOutput io=new InputOutput();

您应该执行如下操作:

final InputOutput io = new InputOutput();
Thread t1=new Thread(new Input(io));
t1.start();
Thread t2=new Thread(new Output());
t2.start();
...
private static class Input {
    private final InputOutput io;
    public Input(InputOutput io) { this.io = io; }
...
private static class Output {
    private final InputOutput io;
    public Output(InputOutput io) { this.io = io; }
...

那么您的 InputOutput class 都在使用 InputOutput class 的同一个实例。当他们在方法上调用 synchronized 时,他们锁定在同一个实例上,当他们调用 wait()notify() 时,信号被另一个线程看到。