java——线程的wait()和notify()

这是一个关于生产者和消费者的线程通信的例子:

package thread_test;

public class PCThread {

    public static void main(String[] args) {
        Queue q = new Queue();
        Producer p = new Producer(q);
        Consumer c = new Consumer(q);
        p.start();
        c.start();
    }
}
//被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行
class Producer extends Thread{
    Queue q;
    
    Producer(Queue q){
        this.q = q;
    }
    
    public void run() {
        for(int i = 1 ; i < 5 ; i ++) {
            q.put(i);
        }
    }
}

class Consumer extends Thread{
    Queue q;
    Consumer(Queue q){
        this.q = q;
    }
    
    public void run() {
        while(true) {
            q.get();
        }
    }
}

class Queue{
    int value = 0;
    boolean isEmpty = true;
    
    public synchronized void put(int v) {
        //如果共享数据没有被消费,则生产者等待
        if(!isEmpty) {
            try {
                System.out.println("生产者等待");
                wait();
            }catch(Exception e) {
                
            }
        }
        value += v;
        isEmpty = false;
        System.out.println("生产者生产数量:" + v);
        notify();
        
    }
    
    public synchronized int get() {
        if(isEmpty) {
            try {
                System.out.println("消费者等待");
                wait();
            }catch(Exception e) {
                
            }
        }
        value --;
        if(value < 1) {
            isEmpty = true;
        }
        System.out.println("消费者消费一个,剩余:" + value);
        notify();
        return value;
    }
}

执行结果:

  我想不通为什么当消费者消费了一个之后,已经触发了notify(),为什么生产者没有开始生产,而是知道剩余为0 时才继续生产?

  这个问题我居然想了好久。。。

原因:

  notify/notifyAll() 的执行只是唤醒沉睡的线程,而不会立即释放锁。消费者消费一个产品后触发了notify()但此时这个消费者线程并没有释放锁,这个时候生产者线程虽然被唤醒,但是由于没有得到锁,仍然不能继续执行。

  当剩余商品为0 时,isEmpty为true,消费者线程执行到了wait()方法,这时候当前的锁被释放,消费者线程让出CPU,进入等待状态。被唤醒的生产者线程拿到了这个锁,继续执行自己的线程。

 

posted @ 2018-11-06 21:52  高圈圈  阅读(456)  评论(0编辑  收藏  举报