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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM