1. 程式人生 > >使用Condition實現多執行緒之間呼叫

使用Condition實現多執行緒之間呼叫

一,object 類的wait,notify和notifyAll

Java 執行緒類也是一個object 類,它的例項都繼承自java.lang.Thread 或其子類。wait,notify和notifyAll是Object類中的方法,常用於執行緒之間排程。

執行緒無資料執行可呼叫wait讓執行緒等待,不佔用CUP資源,提高CPU有效的利用率。例如,執行緒 B 可以等待執行緒 A 的一個訊號,這個訊號會通知執行緒 B 資料已經準備好了,B可以執行業務邏輯。

執行緒之間排程常應用於生產與消費模式下。

利用Object 物件的wait,notify和notifyAll可以實現,但JDK1.5後有更好的替代方法。

二,Condition 類增強類

Condition 類,實現執行緒間的協作,相比使用Object的wait、notify,使用Condition的await、signal這種方式實現執行緒間協作更加安全和高效。因此通常來說比較推薦使用Condition。

Condition依賴於Lock介面,生成一個Condition的基本程式碼是lock.newCondition 呼叫Condition的await和signal方法,必須在lock.lock和lock.unlock之間才可以使用

三,Object與Conditon 對比

Conditon中的await對應Object的wait;

Condition中的signal對應Object的notify;

Condition中的signalAll對應Object的notifyAll。

四,使用Condition 實現生產消費

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by tank  on 2016/11/22.
 * 使用Condition 實現執行緒間生產消費模式
 */
public class ConditionDemo {

    Object queue = new Object[100];//佇列
    int readIndex = 0;//read索引位置
    int writeIndex = 0;
    int dataLen = 0;

    final Lock lock = new ReentrantLock;

    final Condition fullCondition = lock.newCondition;
    final Condition emptyCondition = lock.newCondition;

    public static void main(String[] args) {
        final ConditionDemo demo = new ConditionDemo;


        new Thread {
 @Override
 public void run {
 for (int i = 0; i < 1000; i++) {
 demo.write(i);
 }
 }
        }.start;

        new Thread {
 @Override
 public void run {
 while (true) {
 Object obj = demo.read;
 if (obj != null) {
 System.out.println((Integer) obj);
 }

 }
 }
        }.start;

    }

    //生產
    public void write(Object obj) {
        lock.lock;

        try {

 if (dataLen >= queue.length) {//佇列寫滿了
 System.out.println("佇列寫滿了,等待.....");
 fullCondition.await;
 System.out.println("佇列有空位了,喚醒.....");

 }

 queue[writeIndex] = obj;

 writeIndex++;
 dataLen++;

 if (writeIndex >= queue.length) {
 writeIndex = 0;
 }

 emptyCondition.signal;


        } catch (InterruptedException e) {
 e.printStackTrace;
        } finally {
 lock.unlock;
        }
    }

    //消費
    public Object read {
        lock.lock;

        try {
 if (dataLen <= 0) {
 System.out.println("佇列空了,等待資料.....");
 emptyCondition.await;
 System.out.println("佇列有資料了,喚醒.....");
 }

 Object obj = queue[readIndex];

 readIndex++;
 dataLen--;

 if (readIndex >= queue.length) {
 readIndex = 0;
 }

 fullCondition.signal;

 return obj;


        } catch (InterruptedException e) {
 e.printStackTrace;
        } finally {
 lock.unlock;
        }
        return null;
    }
}