Java併發編程七 生產者消費者模式
生產者-消費者模式是一個經典的多線程設計模式,它爲多線程的協作提供了良好的解決方案。在生產者-消費者模式中,通常有兩類線程,即若干個生產者線程和若干個消費者線程。生產者線程負責提交用戶請求,消費者線程負責處理用戶請求。生產者和消費者之間通過共享內存緩衝區進行通信。
生產者-消費者模式中的內存緩衝區的主要功能是數據在多線程間的共享。此外,通過該緩衝區,可以緩解生產者和消費者之間的性能差。
阻塞隊列實現
舉一個雞下蛋供人吃的例子:
/**
* 雞蛋
* Created by lyyz on 18-5-15.
*/
public class Egg {
private String id;
public Egg(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
/**
* 生產者 雞下蛋裝入籃子
* Created by lyyz on 18-5-15.
*/
public class Chicken implements Runnable {
private String name;
private BlockingQueue<Egg> queue;
private AtomicInteger count = new AtomicInteger();
private volatile boolean isRunning = true;
public Chicken(String name, BlockingQueue<Egg> queue) {
this.name = name;
this.queue = queue;
}
@Override
public void run() {
while(isRunning){
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
count.incrementAndGet();
Egg egg = new Egg("雞-"+name+"-"+count.get());
queue.add(egg);
System.out.println("雞-"+name+"下了第"+count.get()+"個蛋 放入籃子中");
}
}
public void stop(){
isRunning = false;
}
}
/**
* 消費者 人吃籃子中的雞蛋
* Created by lyyz on 18-5-15.
*/
public class People implements Runnable {
private String name;
private BlockingQueue<Egg> queue;
private AtomicInteger count = new AtomicInteger();
private volatile boolean isRunning = true;
public People(String name, BlockingQueue<Egg> queue) {
this.name = name;
this.queue = queue;
}
@Override
public void run() {
while(isRunning){
try {
Thread.sleep(new Random().nextInt(1000));
count.incrementAndGet();
Egg egg = queue.take();
System.out.println("人-"+name+"吃了 "+egg.getId()+"這是吃的第"+count.get()+"個蛋了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stop(){
isRunning = false;
}
}
/**
* 雞下蛋供人吃的例子
* Created by lyyz on 18-5-15.
*/
public class Main {
public static void main(String[] args) {
//阻塞的有界隊列 裝雞蛋的籃子
BlockingQueue<Egg> queue = new ArrayBlockingQueue<Egg>(10);
//創建4只雞
Chicken chicken1 = new Chicken("小紅",queue);
Chicken chicken2 = new Chicken("小黃",queue);
Chicken chicken3 = new Chicken("小黑",queue);
Chicken chicken4 = new Chicken("小綠",queue);
//創建三個人
People people1 = new People("劉備",queue);
People people2 = new People("張飛",queue);
People people3 = new People("關羽",queue);
//線程池
ExecutorService es = Executors.newCachedThreadPool();
es.execute(chicken1);
es.execute(chicken2);
es.execute(chicken3);
es.execute(chicken4);
es.execute(people1);
es.execute(people2);
es.execute(people3);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
chicken1.stop();
chicken2.stop();
chicken3.stop();
chicken4.stop();
while(!queue.isEmpty()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
people1.stop();
people2.stop();
people3.stop();
es.shutdown();
System.out.println("--------------------end------------------------");
}
}