1.成員:
生產者、緩衝區、消費者
2.引入jar包
guava-23.0.jar
3.代碼
package monitor;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.Monitor;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/*
* 用google guava庫Monitor 寫消費者問題
*/
public class MonitorDemo {
private LinkedList<Integer> buffer= new LinkedList<>() ;
private static final int MAX = 10 ;
//記錄生產的數據編號
private static AtomicInteger count = new AtomicInteger(0) ;
//int i ; i++ ;非原子性操作 ; i++ 拆分成多行 ;線程安全問題
private Monitor monitor = new Monitor() ;
//生產數據
public void produce(int value){
//一般方法
// if(buffer.size()<MAX)
// notifyALL(); 若小於MAX,就喚醒消費者
// else
// wait();
try {
//enterWhen:相當於加鎖
monitor.enterWhen( monitor.newGuard( ()-> buffer.size()<MAX ) ) ;
buffer.addLast( value);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
monitor.leave();
System.out.println("生產完畢,緩衝區大小:" + buffer.size());
}
}
//消費數據
public int consume(){
try {
monitor.enterWhen( monitor.newGuard( ()-> ! buffer.isEmpty() ) );
return buffer.removeFirst() ;
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e) ;
}finally {
monitor.leave();
System.out.println("消費完畢,緩衝區大小:" + buffer.size());
}
}
public static void main(String[] args) {
MonitorDemo demo = new MonitorDemo() ;
//原生線程池
ExecutorService executorService = Executors.newFixedThreadPool(6);
//將線程池包裝
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);
//向線程池放入3個生產者
for(int i=0;i<3;i++){
listeningExecutorService.submit( () ->{
while(true){
int result = count.getAndIncrement(); //i++ 0 1 2
demo.produce( result );
System.out.println("生產:"+ result);
}
} ) ;
}
//向線程池放入3個消費者
for(int i=0;i<3;i++){
while(true){
int result = demo.consume() ;
System.out.println("消費" +result);
}
}
}
}