扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章主要介绍“Java多线程生产者消费者模型实例代码”,在日常操作中,相信很多人在Java多线程生产者消费者模型实例代码问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java多线程生产者消费者模型实例代码”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
创新互联是一家从事企业网站建设、成都网站建设、网站设计、行业门户网站建设、网页设计制作的专业网站设计公司,拥有经验丰富的网站建设工程师和网页设计人员,具备各种规模与类型网站建设的实力,在网站建设领域树立了自己独特的设计风格。自公司成立以来曾独立设计制作的站点1000多家。生产者消费者模型
生产者:生产任务的个体;
消费者:消费任务的个体;
缓冲区:是生产者和消费者之间的媒介,对生产者和消费者解耦。
当
缓冲区元素为满,生产者无法生产,消费者继续消费;
缓冲区元素为空,消费者无法消费,生产者继续生产;
wait()/notify()生产者消费者模型
制作一个简单的缓冲区ValueObject,value为空表示缓冲区为空,value不为空表示缓冲区满
public class ValueObject { public static String value = "";}
生产者,缓冲区满则wait(),不再生产,等待消费者notify(),缓冲区为空则开始生产
public class Producer { private Object lock; public Producer(Object lock) { this.lock = lock; } public void setValue() { try { synchronized (lock) { if (!ValueObject.value.equals("")) lock.wait(); String value = System.currentTimeMillis() + "_" + System.nanoTime(); System.out.println("Set的值是:" + value); ValueObject.value = value; lock.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } }}
消费者,缓冲区为空则wait(),等待生产者notify(),缓冲区为满,消费者开始消费
public class Customer { private Object lock; public Customer(Object lock) { this.lock = lock; } public void getValue() { try { synchronized (lock) { if (ValueObject.value.equals("")) lock.wait(); System.out.println("Get的值是:" + ValueObject.value); ValueObject.value = ""; lock.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } }}
main方法,启动一个生产者和一个消费者
public class Main { public static void main(String[] args) { Object lock = new Object(); final Producer producer = new Producer(lock); final Customer customer = new Customer(lock); Runnable producerRunnable = new Runnable() { public void run() { while (true) { producer.setValue(); } } }; Runnable customerRunnable = new Runnable() { public void run() { while (true) { customer.getValue(); } } }; Thread producerThread = new Thread(producerRunnable); Thread CustomerThread = new Thread(customerRunnable); producerThread.start(); CustomerThread.start(); }}
运行结果如下
Set的值是:1564733938518_27520480474279Get的值是:1564733938518_27520480474279Set的值是:1564733938518_27520480498378Get的值是:1564733938518_27520480498378Set的值是:1564733938518_27520480540254Get的值是:1564733938518_27520480540254······
生产者和消费者交替运行,生产者生产一个字符串,缓冲区为满,消费者消费一个字符串,缓冲区为空,循环往复,满足生产者/消费者模型。
await()/signal()生产者/消费者模型
缓冲区
public class ValueObject { public static String value = "";}
ThreadDomain48继承ReentrantLock,set方法生产,get方法消费
public class ThreadDomain48 extends ReentrantLock{ private Condition condition = newCondition(); public void set() { try { lock(); while (!"".equals(ValueObject.value)) condition.await(); ValueObject.value = "123"; System.out.println(Thread.currentThread().getName() + "生产了value, value的当前值是" + ValueObject.value); condition.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { unlock(); } } public void get() { try { lock(); while ("".equals(ValueObject.value)) condition.await(); ValueObject.value = ""; System.out.println(Thread.currentThread().getName() + "消费了value, value的当前值是" + ValueObject.value); condition.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { unlock(); } }}
MyThread41启动两个生产线程和一个消费线程
public class MyThread41 { public static void main(String[] args) { final ThreadDomain48 td = new ThreadDomain48(); Runnable producerRunnable = new Runnable() { public void run() { for (int i = 0; i < Integer.MAX_VALUE; i++) td.set(); } }; Runnable customerRunnable = new Runnable() { public void run() { for (int i = 0; i < Integer.MAX_VALUE; i++) td.get(); } }; Thread ProducerThread1 = new Thread(producerRunnable); ProducerThread1.setName("Producer1"); Thread ProducerThread2 = new Thread(producerRunnable); ProducerThread2.setName("Producer2"); Thread ConsumerThread = new Thread(customerRunnable); ConsumerThread.setName("Consumer"); ProducerThread1.start(); ProducerThread2.start(); ConsumerThread.start(); }}
输出结果如下
Producer1生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer1生产了value, value的当前值是123
为什么Producer2无法生产,消费者无法消费呢?是因为此时缓冲区为满,Producer1的notify()应该唤醒Consumer却唤醒了Producer2,导致Producer2因为缓冲区为满和Consumer没有被唤醒而处于waiting状态,此时三个线程均在等待,出现了假死。
解决方案有两种:
1.让生产者唤醒所有线程,在set方法中使用condition.signalAll();
2.使用两个Condition,生产者Condition和消费者Condition,唤醒指定的线程;
正常输入如下:
······Producer2生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer2生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer2生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer1生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer1生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer1生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer1生产了value, value的当前值是123Consumer消费了value, value的当前值是Producer1生产了value, value的当前值是123Consumer消费了value, value的当前值是······
到此,关于“Java多线程生产者消费者模型实例代码”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流