wait(),notify(),notifyAll()的理解与使用

这三个方法由于需要控制对对象的控制权(monitor),所以属于Object而不是属于线程。

wait(),会把持有该对象线程的对象控制权交出去,然后处于等待状态。

notify(),会通知某个正在等待这个对象的控制权的线程可以继续运行。

nofifyAll(),会通知所有等待这个对象控制权的线程继续运行,如果有多个正在等待该对象控制权时,具体唤醒哪个线程,就由操作系统进行调度。

 

注意:

1.生产者,消费者必须要对同一份资源进行操作。

2.无论是执行对象的wait、notify还是notifyAll方法,必须保证当前运行的线程取得了该对象的控制权(monitor)

 

生产者:

 

package com.currentPro.waitAndnotify;

import java.util.ArrayList;
import java.util.List;

public class Producer implements Runnable{

    private List<Integer> taskQueue = new ArrayList<Integer>();
    
    //生产的量
    private final int MAX_CAPACITY;
    
    public Producer(List<Integer> sharedQueue,int size){
        this.taskQueue = sharedQueue; 
        this.MAX_CAPACITY = size;
    }
    
    @Override
       public void run()
       {
          int counter = 1;
          while (true)
          {
             try
             {
               synchronized (taskQueue)
                     {
                        while (taskQueue.size() == MAX_CAPACITY)
                        {
                           System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
                           taskQueue.wait();
                        }
                        Thread.sleep(1000);
                        taskQueue.add(counter);
                        System.out.println("Produced: " + counter);
                        counter++;
                        //唤醒正在等待的消费者,但是消费者是不是能获取到资源,由系统调度。
                        taskQueue.notifyAll();
                     }
             } 
             catch (InterruptedException ex)
             {
                ex.printStackTrace();
             }
          }
       }
    
}

 

消费者:

 

package com.currentPro.waitAndnotify;

import java.util.List;

public class Consumer implements Runnable{

    private final List<Integer> taskQueue ;
    
    
    public Consumer(List<Integer> sharedQueue){
        this.taskQueue = sharedQueue; 
    }
    
    @Override
       public void run()
       {
          while (true)
          {
             try
             {
                 synchronized (taskQueue)
                     {
                        while (taskQueue.isEmpty())
                        {
                           System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
                           taskQueue.wait();
                        }
                        Thread.sleep(1000);
                        int i = (Integer) taskQueue.remove(0);
                        System.out.println("Consumed: " + i);
                        taskQueue.notifyAll();
                     }
             } catch (InterruptedException ex)
             {
                ex.printStackTrace();
             }
          }
       }
}

 

测试代码:

 

package com.currentPro.waitAndnotify;

import java.util.ArrayList;
import java.util.List;

public class Test {

    
    
    public static void main(String[] args) throws InterruptedException {
        //共享资源
        List<Integer> taskQueue = new ArrayList<Integer>();
        
        int MAX_CAPACITY = 5;
        //创建生产者线程
        Thread producer = new Thread(new Producer(taskQueue,MAX_CAPACITY),"producer");
        
        //创建消费者线程
        Thread consumer = new Thread(new Consumer(taskQueue),"consumer");
        
        consumer.start();
        Thread.sleep(2000);
        producer.start();
        
    }
}

 

参考资料

http://longdick.iteye.com/blog/453615

http://howtodoinjava.com/core-java/multi-threading/how-to-work-with-wait-notify-and-notifyall-in-java/

http://www.cnblogs.com/dolphin0520/p/3920385.html

posted @ 2016-02-23 11:24  倔强的鸭子  阅读(2759)  评论(0编辑  收藏  举报