java骞跺彂 locks鍖咃細Condition(浜

java骞跺彂 locks鍖咃細Condition(浜?

鏈枃鍩烘湰鏄疛DK鏂囨。涓殑璇存槑鍐呭锛屼絾鏄凡缁忓緢濂界殑瑙i噴浜咰ondition瀵硅薄鐨勪娇鐢ㄦ柟娉曘€?/p>

Condition 灏?Object 鐩戣鍣ㄦ柟娉曪紙wait銆乶otify 鍜?notifyAll锛夊垎瑙f垚鎴劧涓嶅悓鐨勫璞★紝浠ヤ究閫氳繃灏嗚繖浜涘璞′笌浠绘剰 Lock 瀹炵幇缁勫悎浣跨敤锛屼负姣忎釜瀵硅薄鎻愪緵澶氫釜绛夊緟 set锛坵ait-set锛夈€傚叾涓紝Lock 鏇夸唬浜?synchronized 鏂规硶鍜岃鍙ョ殑浣跨敤锛孋ondition 鏇夸唬浜?Object 鐩戣鍣ㄦ柟娉曠殑浣跨敤銆偮?/p>

鏉′欢锛堜篃绉颁负鏉′欢闃熷垪 鎴栨潯浠跺彉閲忥級涓虹嚎绋嬫彁渚涗簡涓€涓惈涔夛紝浠ヤ究鍦ㄦ煇涓姸鎬佹潯浠剁幇鍦ㄥ彲鑳戒负 true 鐨勫彟涓€涓嚎绋嬮€氱煡瀹冧箣鍓嶏紝涓€鐩存寕璧疯绾跨▼锛堝嵆璁╁叾鈥滅瓑寰呪€濓級銆傚洜涓鸿闂鍏变韩鐘舵€佷俊鎭彂鐢熷湪涓嶅悓鐨勭嚎绋嬩腑锛屾墍浠ュ畠蹇呴』鍙椾繚鎶わ紝鍥犳瑕佸皢鏌愮褰㈠紡鐨勯攣涓庤鏉′欢鐩稿叧鑱斻€傜瓑寰呮彁渚涗竴涓潯浠剁殑涓昏灞炴€ф槸锛氫互鍘熷瓙鏂瑰紡 閲婃斁鐩稿叧鐨勯攣锛屽苟鎸傝捣褰撳墠绾跨▼锛屽氨鍍?Object.wait 鍋氱殑閭f牱銆偮?/p>

Condition 瀹炰緥瀹炶川涓婅缁戝畾鍒颁竴涓攣涓娿€傝涓虹壒瀹?Lock 瀹炰緥鑾峰緱 Condition 瀹炰緥锛岃浣跨敤鍏?newCondition() 鏂规硶銆偮?/p>

浣滀负涓€涓ず渚嬶紝鍋囧畾鏈変竴涓粦瀹氱殑缂撳啿鍖猴紝瀹冩敮鎸?put 鍜?take 鏂规硶銆傚鏋滆瘯鍥惧湪绌虹殑缂撳啿鍖轰笂鎵ц take 鎿嶄綔锛屽垯鍦ㄦ煇涓€涓」鍙樺緱鍙敤涔嬪墠锛岀嚎绋嬪皢涓€鐩撮樆濉烇紱濡傛灉璇曞浘鍦ㄦ弧鐨勭紦鍐插尯涓婃墽琛?put 鎿嶄綔锛屽垯鍦ㄦ湁绌洪棿鍙樺緱鍙敤涔嬪墠锛岀嚎绋嬪皢涓€鐩撮樆濉炪€傛垜浠枩娆㈠湪鍗曠嫭鐨勭瓑寰?set 涓繚瀛?put 绾跨▼鍜?take 绾跨▼锛岃繖鏍峰氨鍙互鍦ㄧ紦鍐插尯涓殑椤规垨绌洪棿鍙樺緱鍙敤鏃跺埄鐢ㄦ渶浣宠鍒掞紝涓€娆″彧閫氱煡涓€涓嚎绋嬨€傚彲浠ヤ娇鐢ㄤ袱涓?Condition 瀹炰緥鏉ュ仛鍒拌繖涓€鐐广€偮?/p>

浠g爜瀹炰緥锛?/p>

package com.mutex;

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

/**
 * 瀹炵幇鑷繁鐨勯樆濉為槦鍒?
 */
public class MyBlockingQueue<T> {

	private final Lock lock = new ReentrantLock();

	private Condition notFull = lock.newCondition();
	private Condition notEmpty = lock.newCondition();

	private final Object[] items = new Object[100];
	private int putptr, takeptr, count;

	public void put(T x) {
		lock.lock();
		try {
			while (count == items.length)
				notFull.await();

			items[putptr] = x;
			if (++putptr == items.length)
				putptr = 0;

			++count;

			notEmpty.signal();

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

	public T take() {
		lock.lock();
		try {
			while (count == 0)
				notEmpty.await();

			T x = (T) items[takeptr];
			if (++takeptr == items.length)
				takeptr = 0;

			--count;

			notFull.signal();

			return x;
		} catch (InterruptedException e) {
			// todo
			return null;
		} finally {
			lock.unlock();
		}

	}

	public static void main(String[] args) {

		final MyBlockingQueue<String> bq = new MyBlockingQueue<String>();

		new Thread() {
			public void run() {
				int count = 0;
				while (true) {
					++count;
					bq.put("test: " + count);
				}
			}
		}.start();

		new Thread() {
			public void run() {
				while (true) {
					System.out.println(bq.take());
				}
			}
		}.start();
	}

}