使用通知进行线程间通信

时间:2014-03-08 00:39:14

标签: java

我尝试运行“Herbert Schildt的JAVA 2”一书中编写的代码。这是代码

class Q 
{
    int n;
    boolean valueSet = false;

    synchronized int get() {
        if(!valueSet) {
            try {
                wait();
            } catch(InterruptedException e) {
                System.out.println("InterruptedException caught");
            }
        }
        System.out.println("Got: " + n);

        valueSet=false;
        notify();

        return n;
    }

    synchronized void put(int n) {
        System.out.println("Put method called");

        if(valueSet) {
            try {
                System.out.println("Put method if check called");
                wait();
            } catch(InterruptedException e) {
                System.out.println("InterruptedException caught");
            }

            this.n=n;
            valueSet=true;

            System.out.println("Put: " + n);

            notify();
        }
    }
}


class Producer implements Runnable {
    Q q;
    Producer(Q q) {
        this.q=q;
        new Thread(this,"Producer").start();
    }

    public void run() {
        int i=0;

        while(true) {
            q.put(i++);
        }
    }
}


class Consumer implements Runnable {
    Q q;

    Consumer(Q q) {
        this.q=q;
        new Thread(this,"Consumer").start();
    }

    public void run() {
        while(true) {
            q.get();
        }
    }
}

class PcFixed {
    public static void main(String[] args) {
        System.out.println("main thread started");
        Q obj = new Q();
        new Producer(obj);
        new Consumer(obj);
    }
}

它应该给出的输出是

  

把:1

     

GOT:1

     

把:2

     

GOT:2

     

把:3

     

GOT:3

     

把:4

     

GOT:4

     

把:5

     

GOT:5

但我的问题是,当线程在Producer构造函数中启动时,它调用run(),然后进入调用while的{​​{1}}循环。但它一次又一次地执行q.put()的第一个语句(无限循环)。为什么这样做?

1 个答案:

答案 0 :(得分:0)

valueSet永远不会设置为true,因为唯一的true赋值在if(valueSet){...}块中。

您需要将this.n = n和后续行移出if(valueSet){...}块。

BTW,虽然理解这些东西有其用途,但在java.util.concurrent中使用更高级别的并发类(例如阻塞队列)通常是目前更好的方法。