packagecom.concurrent.test;importjava.util.Stack;importjava.util.concurrent.ArrayBlockingQueue;importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.ReentrantLock;/*** @Description: 三种方法实现生产者/消费者*/
public classThreadSynchronizeTest {public static voidmain(String[] args) {
ProducerConsumer producerConsumer= newProducerConsumerViaBlockingQueue();
producerConsumer.test();
}
}abstract classProducerConsumer {protected int capacity = 10;protected int element = 0;protected abstract void produce() throwsInterruptedException;protected abstract void consume() throwsInterruptedException;public voidtest() {
Thread producer= new Thread(newRunnable() {
@Overridepublic voidrun() {while (true) {try{
produce();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consumer= new Thread(newRunnable() {
@Overridepublic voidrun() {while (true) {try{
consume();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consumer.start();
}
}/*** 方法一:ReentrantLock结合Condition*/
class ProducerConsumerViaReentrantLock extendsProducerConsumer {private Stack stack = new Stack<>();private ReentrantLock lock = newReentrantLock();private Condition notFull =lock.newCondition();private Condition notEmpty =lock.newCondition();
@Overrideprotected void produce() throwsInterruptedException {try{
lock.lock();if (stack.size() ==capacity) {
notFull.await();
}++element;
System.out.println(Thread.currentThread().getId()+ "," + Thread.currentThread().getName() + " produce " +element);
stack.push(element);
notEmpty.signalAll();
Thread.sleep(1000L);
}finally{
lock.unlock();
}
}
@Overrideprotected void consume() throwsInterruptedException {try{
lock.lock();if(stack.isEmpty()) {
notEmpty.await();
}int element =stack.pop();
System.out.println(Thread.currentThread().getId()+ "," + Thread.currentThread().getName() + " consume " +element);
notFull.signalAll();
}finally{
lock.unlock();
}
}
}/*** 方法二:synchronized 结合 wait、notify、notifyAll*/
class ProducerConsumerViaObjectLock extendsProducerConsumer {private Stack stack = new Stack<>();private Object lock = newObject();
@Overrideprotected void produce() throwsInterruptedException {/** 1,lock为监视器
* 2,wait/notify/notifyAll方法必须在synchronized块内调用
* 3,调用wait/notify/notifyAll方法但不持有监视器的使用权将会抛出java.lang.IllegalMonitorStateException*/
synchronized(lock) {if (stack.size() ==capacity) {
lock.wait();
}++element;
System.out.println(Thread.currentThread().getId()+ "," + Thread.currentThread().getName() + " produce " +element);
stack.push(element);
lock.notifyAll();
Thread.sleep(1000L);
}
}
@Overrideprotected void consume() throwsInterruptedException {synchronized(lock) {if(stack.isEmpty()) {
lock.wait();
}int element =stack.pop();
System.out.println(Thread.currentThread().getId()+ "," + Thread.currentThread().getName() + " consume " +element);
lock.notifyAll();
}
}
}/*** 方法三:BlockingQueue*/
class ProducerConsumerViaBlockingQueue extendsProducerConsumer {private BlockingQueue queue = new ArrayBlockingQueue<>(capacity);
@Overrideprotected void produce() throwsInterruptedException {++element;
System.out.println(Thread.currentThread().getId()+ "," + Thread.currentThread().getName() + " produce " +element);
queue.put(element);
Thread.sleep(1000L);
}
@Overrideprotected void consume() throwsInterruptedException {int element =queue.take();
System.out.println(Thread.currentThread().getId()+ " consume " +element);
Thread.sleep(10000L);
}
}