手寫一個單線程的生產者和消費者實現,實現生產者生產一個數字,如果已經生產線程等待,調用消費者消費這個數字,取消等待再次生產。
流程
單線程實現生產者消費者
public class OtherService {
private int i = 1;
// 添加一個鎖
final private Object LOCK = new Object();
private Boolean flage = false;
// 生產者
public void produck(){
synchronized (LOCK){
if (flage){
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
i++;
System.out.println("P"+i);
LOCK.notify();
flage = true;
}
}
}
// 消費者
public void Customer(){
synchronized (LOCK){
if(flage){
// 消費
System.out.println("C"+i);
// 啓用線程
LOCK.notify();
flage = false;
}else{
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
此種方法只能實現單線程的,無法實現多線程,如果同時創建多個生產者和消費者就會出現錯誤。
public static void main(String[] args) {
OtherService o = new OtherService();
Stream.of("p1","p2").forEach(
n -> new Thread (){
@Override
public void run() {
while (true)
o.produck();
}
}.start()
);
Stream.of("C1","C2").forEach(c ->
new Thread(){
@Override
public void run() {
while (true)
o.Customer();
}
}.start()
);
}
線程會出現假死。多線程如何解決呢。
多線程實現生產者消費者
將notify修改爲notifyAll可以解決一個生產者對應多個消費者的問題,不會有一個生產者對應多個消費者的錯誤。爲方便測試可以添加多個線程測試。