wait()和notify()相关的问题

时间:2017-05-22 13:29:37

标签: java multithreading java-threads

我只想使用线程从1到10打印出来。但是我的代码将在数字1处停止.input()将提供从1到10的变量,而output()将打印出它们。首先执行input()然后输出()。之后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();
    }
}

2 个答案:

答案 0 :(得分:1)

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();
    }

}

答案 1 :(得分:0)

  

我只想使用线程从1到10打印出来。但是我的代码将停在第1位。

[[其他答案似乎解决了你的问题,但它没有解释正在发生什么以及修复工作的原因。 ]

问题是两个线程都在不同的对象上调用padding: 0;synchronize以及notify()。当线程使用这些信号进行通信时,它们都需要共享同一个对象实例。您正在创建2个wait()个对象,因此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; } ... Input类都使用Output类的相同实例。当他们在方法上调用InputOutput时,他们会锁定同一个实例,当他们调用synchronizedwait()时,其他线程会看到这些信号。