以下的代码示例:先使用了synchronized关键字来实现生产者消费者,而后使用了JUC中的lock及其condition来实现生产者消费者
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class JucTest1 { public static void main(String[] args) { Ticket ticket = new Ticket(); for (int i=0;i<4;i++) { new Thread(()-> { try { for (int j=0;j<10;j++) { ticket.produce(); } } catch (InterruptedException e) { e.printStackTrace(); } },"A"+i).start(); new Thread(()-> { try { for (int j=0;j<10;j++) { ticket.consumer(); } } catch (InterruptedException e) { e.printStackTrace(); } },"B"+i).start(); } JUCTicket jucTicket = new JUCTicket(); for (int i=0;i<4;i++) { new Thread(()-> { for (int j=0;j<10;j++) { jucTicket.produce(); } },"C"+i).start(); new Thread(()-> { for (int j=0;j<10;j++) { jucTicket.consumer(); } },"D"+i).start(); } } } //使用synchronized来模拟生产者消费者问题 class Ticket { private int number = 0; //使用synchronized来实现并发,synchronized可以锁当前对象 synchronized void produce() throws InterruptedException { //如果使用if判断存在虚假唤醒问题,也就是两个线程同时进入,所以我们一般把等待的内容放到where中 while (number != 0) { //等待消费者消费 this.wait(); } number++; System.out.println(Thread.currentThread().getName()+"生产后,number="+number); //通知其它线程我生产完成了 this.notifyAll(); } synchronized void consumer() throws InterruptedException { while (number == 0) { //等待生产者生产 this.wait(); } number--; System.out.println(Thread.currentThread().getName()+"消费后,number="+number); //通知其它线程我消费完成了 this.notifyAll(); } } //使用lock锁来模拟生产者消费者问题 class JUCTicket { private int number = 0; private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); //condition.signalAll();相当于this.notifyAll(); //condition.await();相当于this.wait(); //使用synchronized来实现并发,synchronized可以锁当前对象 void produce(){ lock.lock(); try { while (number != 0) { //等待消费者消费 condition.await(); } number++; System.out.println(Thread.currentThread().getName()+"生产后,number="+number); //通知其它线程我生产完成了 condition.signalAll(); }catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } void consumer(){ lock.lock(); try { while (number == 0) { //等待生产者生产 condition.await(); } number--; System.out.println(Thread.currentThread().getName()+"消费后,number="+number); //通知其它线程我生产完成了 condition.signalAll(); }catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } }
运行的结果:生产者只能生产一个,生产后,需要等待其它消费者进行消费,消费者消费完成后通知生产继续生产
B0消费后,number=0
A0生产后,number=1
B0消费后,number=0
A1生产后,number=1
B1消费后,number=0
A0生产后,number=1
B2消费后,number=0