1.生產者消費者在處理併發時是很常用的處理方式 是很有必要掌握的。
2.Lock其實就相當於傳統的synchronize Condition的await()相當於wait() signal()相當於notify().
3.沒有使用傳統的 wait() 和notify()的原因是 Condition可以有多個,能夠用來解決更加複雜的情況.
直接上代碼:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConsumerAndProducter {
public static void main(String[] args) {
new ConsumerAndProducter().work();
}
int length = 8;// 倉庫最大容量
Lock lock = new ReentrantLock();
Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();
List<Productor> Productors = new ArrayList<>();
private void work() {
new Thread(new Runnable() {
public void run() {
consume();
}
}).start();
new Thread(new Runnable() {
public void run() {
consume();
}
}).start();
new Thread(new Runnable() {
public void run() {
product();
}
}).start();
}
/**
* 消費
*/
private void consume() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
lock.lock();
try {
while (Productors.size() == 0) {
System.out.println("容器爲空 等待生產"+Thread.currentThread().getName());
notEmpty.await();
}
Productors.remove(0);
System.out.println("消費了一個產品"+Thread.currentThread().getName());
System.out.println("容器有空餘 通知生產"+Thread.currentThread().getName());
notFull.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 生產
*/
private void product() {
while(true){
try {
Thread.sleep(500); //生產效率
} catch (InterruptedException e1) {
e1.printStackTrace();
}
lock.lock();
try {
while (Productors.size() == 8) {
System.out.println("容器已滿 等待消費"+Thread.currentThread().getName());
notFull.await();
}
Productors.add(new Productor()); //生產機器數
System.out.println("產品已生產 通知可以消費"+Thread.currentThread().getName());
notEmpty.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 產品
* @author z2wenfa
*
*/
private class Productor {
public Productor() {
}
}
}