?? conditiontest.java
字號:
package book.j2se5.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 有時候線程取得lock后需要在一定條件下才能做某些工作,比如說經典的Producer和Consumer問題。
* 在Java 5.0以前,這種功能是由Object類的wait(), notify()和notifyAll()等方法實現的,
* 在5.0里面,這些功能集中到了Condition這個接口來實現。
*/
public class ConditionTest {
/**
* 籃子程序,這里為了簡化問題,籃子中最多只能有一個蘋果。
* Consumer必須在籃子里有蘋果的時候才能吃蘋果,否則它必須暫時放棄對籃子的鎖定,
* 等到Producer往籃子里放了蘋果后再去拿來吃。而Producer必須等到籃子空了才能往里放蘋果,
* 否則它也需要暫時解鎖等Consumer把蘋果吃了才能往籃子里放蘋果。
*/
public static class Basket {
// 鎖
Lock lock = new ReentrantLock();
// 根據鎖產生Condition對象
Condition produced = lock.newCondition();
Condition consumed = lock.newCondition();
// 籃子中的蘋果數,最多為1
int num = 0;
/**
* 生產蘋果,往籃子里放
* @throws InterruptedException
*/
public void produce() throws InterruptedException {
// 獲得鎖
lock.lock();
System.out.println("Producer get a lock...");
try {
// 判斷是否滿足生產條件
while (num == 1) {
// 如果有蘋果,則不生產,放棄鎖,進入睡眠
// 等待消費者消費
System.out.println("Producer sleep...");
consumed.await();
System.out.println("Producer awaked...");
}
/*生產蘋果*/
Thread.sleep(500);
System.out.println("Producer produced an Apple.");
num = 1;
// 通知等待produced Condition的線程
produced.signal();
} finally {
lock.unlock();
}
}
/**
* 消費蘋果,從籃子中取
* @throws InterruptedException
*/
public void consume() throws InterruptedException {
// 獲得鎖
lock.lock();
System.out.println("Consumer get a lock...");
try {
// 判斷是否滿足消費條件
while (num == 0) {
// 如果沒有蘋果,無法消費,則放棄鎖,進入睡眠
// 等待生產者生產蘋果
System.out.println("Consumer sleep...");
produced.await();
System.out.println("Consumer awaked...");
}
/*吃蘋果*/
Thread.sleep(500);
System.out.println("Consumer consumed an Apple.");
num = 0;
// 發信號喚醒某個等待consumed Condition的線程
consumed.signal();
} finally {
lock.unlock();
}
}
}
/**
* 測試Basket程序
*/
public static void testBasket() throws Exception {
final Basket basket = new Basket();
// 定義一個producer
Runnable producer = new Runnable() {
public void run() {
try {
basket.produce();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
};
// 定義一個consumer
Runnable consumer = new Runnable() {
public void run() {
try {
basket.consume();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
};
// 各產生3個consumer和producer
ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 3; i++){
service.submit(producer);
}
for (int i = 0; i < 3; i++){
service.submit(consumer);
}
service.shutdown();
}
public static void main(String[] args) throws Exception {
ConditionTest.testBasket();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -