package interview; import java.util.LinkedList; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * 写一个固定容量同步容器,拥有put和get方法,以及getCount方法 * * 使用Lock和Condition来实现 * 对比两种方式,Condition的方式可以更加精确的指定哪些线程被唤醒 */ public class ProducerConsumer<T> { final private LinkedList<T> list = new LinkedList<>(); final private int MAX=10; private int count=0; private Lock lock = new ReentrantLock(); private Condition producer = lock.newCondition(); private Condition consumer = lock.newCondition(); public void put(T t) { lock.lock(); try { while(list.size()==MAX) { producer.await(); } list.add(t); ++count; consumer.signalAll(); }catch(Exception e) { }finally { lock.unlock(); } } public T get() { T t=null; lock.lock(); try { while(list.size()==0) { consumer.await(); } t = list.removeFirst(); count--; producer.signalAll(); }catch(Exception e) { }finally { lock.unlock(); } return t; } public static void main(String[] args) { ProducerConsumer<String> pc = new ProducerConsumer<>(); //消费者线程 for(int i=0;i<10;i++) { new Thread(() -> { for(int j=0;j<5;j++) { System.out.println(pc.get()); } },"c"+i).start(); } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } //生产者线程 for(int i=0; i<2;i++) { new Thread(() -> { for(int j=0;j<25;j++) { pc.put(Thread.currentThread().getName()+" "+j); } },"p"+i).start(); } } }