1. 程式人生 > >wait() 和notify() nofifyAll()

wait() 和notify() nofifyAll()

這三個方法由於需要控制對物件的控制權(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();
        
    }
}

複製程式碼