当前位置: 首页 > news >正文 微网站 手机网站如何建淘客网站 news 2025/10/27 3:06:40 微网站 手机网站,如何建淘客网站,建设网站的企业邮箱,兼职做一篇微信的网站生产者-消费者模式是多线程并发编程中一个非常经典的模式#xff0c;它通过解耦生产者和消费者的关系#xff0c;使得两者可以独立工作#xff0c;从而提高系统的并发性和可扩展性。本文将详细介绍生产者-消费者模式的概念、实现方式以及应用场景。 1 生产者-消费者模式概述…生产者-消费者模式是多线程并发编程中一个非常经典的模式它通过解耦生产者和消费者的关系使得两者可以独立工作从而提高系统的并发性和可扩展性。本文将详细介绍生产者-消费者模式的概念、实现方式以及应用场景。 1 生产者-消费者模式概述 生产者-消费者模式包含两类线程 生产者线程负责生产数据并将数据放入共享数据区。消费者线程负责从共享数据区中取出数据并进行消费。 为了解耦生产者和消费者的关系通常会使用一个共享的数据区域如队列作为缓冲区。生产者将数据放入缓冲区消费者从缓冲区中取出数据两者之间不需要直接通信。 共享数据区域需要具备以下功能 当缓冲区已满时阻塞生产者线程防止其继续生产数据。当缓冲区为空时阻塞消费者线程防止其继续消费数据。 2 wait/notify 的消息通知机制 wait/notify 是 Java 中用于线程间通信的经典机制通过 Object 类提供的 wait 和 notify/notifyAll 方法可以实现线程的等待和唤醒。下面将详细介绍 wait/notify 机制的使用方法、注意事项以及常见问题的解决方案。 2.1 wait 方法 wait 方法用于将当前线程置入休眠状态直到其他线程调用 notify 或 notifyAll 方法唤醒它。 调用条件wait 方法必须在同步方法或同步块中调用即线程必须持有对象的监视器锁monitor lock。释放锁调用 wait 方法后当前线程会释放锁并进入等待状态。异常如果线程在调用 wait 方法时没有持有锁则会抛出 IllegalMonitorStateException 异常。 示例代码 synchronized (lockObject) {try {lockObject.wait();} catch (InterruptedException e) {e.printStackTrace();} }2.2 notify 方法 notify 方法用于唤醒一个正在等待该对象监视器锁的线程。 调用条件notify 方法也必须在同步方法或同步块中调用线程必须持有对象的监视器锁。唤醒线程notify 方法会从等待队列中随机选择一个线程进行唤醒使其从 wait 方法处退出并进入同步队列等待获取锁。释放锁调用 notify 后当前线程不会立即释放锁而是在退出同步块后才会释放锁。 示例代码 synchronized (lockObject) {lockObject.notify(); }2.3 notifyAll 方法 notifyAll 方法与 notify 方法类似但它会唤醒所有正在等待该对象监视器锁的线程。 唤醒所有线程notifyAll 方法会将所有等待队列中的线程移入同步队列等待获取锁。 示例代码 synchronized (lockObject) {lockObject.notifyAll(); }2.4 wait/notify 机制的常见问题及解决方案 2.4.1 notify 早期通知 问题描述如果 notify 方法在 wait 方法之前被调用可能会导致通知遗漏使得等待的线程一直处于阻塞状态。 示例代码 public class EarlyNotify {private static String lockObject ;public static void main(String[] args) {WaitThread waitThread new WaitThread(lockObject);NotifyThread notifyThread new NotifyThread(lockObject);notifyThread.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}waitThread.start();}static class WaitThread extends Thread {private String lock;public WaitThread(String lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {try {System.out.println(Thread.currentThread().getName() 进去代码块);System.out.println(Thread.currentThread().getName() 开始wait);lock.wait();System.out.println(Thread.currentThread().getName() 结束wait);} catch (InterruptedException e) {e.printStackTrace();}}}}static class NotifyThread extends Thread {private String lock;public NotifyThread(String lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {System.out.println(Thread.currentThread().getName() 进去代码块);System.out.println(Thread.currentThread().getName() 开始notify);lock.notify();System.out.println(Thread.currentThread().getName() 结束开始notify);}}} }解决方案添加一个状态标志在 wait 方法调用前判断状态是否已经改变。 优化后的代码 public class EarlyNotify {private static String lockObject ;private static boolean isWait true;public static void main(String[] args) {WaitThread waitThread new WaitThread(lockObject);NotifyThread notifyThread new NotifyThread(lockObject);notifyThread.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}waitThread.start();}static class WaitThread extends Thread {private String lock;public WaitThread(String lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {try {while (isWait) {System.out.println(Thread.currentThread().getName() 进去代码块);System.out.println(Thread.currentThread().getName() 开始wait);lock.wait();System.out.println(Thread.currentThread().getName() 结束wait);}} catch (InterruptedException e) {e.printStackTrace();}}}}static class NotifyThread extends Thread {private String lock;public NotifyThread(String lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {System.out.println(Thread.currentThread().getName() 进去代码块);System.out.println(Thread.currentThread().getName() 开始notify);lock.notifyAll();isWait false;System.out.println(Thread.currentThread().getName() 结束开始notify);}}} }2.4.2 等待条件发生变化 问题描述如果线程在等待时接收到通知但之后等待的条件发生了变化可能会导致程序出错。 示例代码 public class ConditionChange {private static ListString lockObject new ArrayList();public static void main(String[] args) {Consumer consumer1 new Consumer(lockObject);Consumer consumer2 new Consumer(lockObject);Productor productor new Productor(lockObject);consumer1.start();consumer2.start();productor.start();}static class Consumer extends Thread {private ListString lock;public Consumer(List lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {try {if (lock.isEmpty()) {System.out.println(Thread.currentThread().getName() list为空);System.out.println(Thread.currentThread().getName() 调用wait方法);lock.wait();System.out.println(Thread.currentThread().getName() wait方法结束);}String element lock.remove(0);System.out.println(Thread.currentThread().getName() 取出第一个元素为 element);} catch (InterruptedException e) {e.printStackTrace();}}}}static class Productor extends Thread {private ListString lock;public Productor(List lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {System.out.println(Thread.currentThread().getName() 开始添加元素);lock.add(Thread.currentThread().getName());lock.notifyAll();}}} }解决方案在 wait 方法退出后再次检查等待条件。 优化后的代码 public class ConditionChange {private static ListString lockObject new ArrayList();public static void main(String[] args) {Consumer consumer1 new Consumer(lockObject);Consumer consumer2 new Consumer(lockObject);Productor productor new Productor(lockObject);consumer1.start();consumer2.start();productor.start();}static class Consumer extends Thread {private ListString lock;public Consumer(List lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {try {while (lock.isEmpty()) {System.out.println(Thread.currentThread().getName() list为空);System.out.println(Thread.currentThread().getName() 调用wait方法);lock.wait();System.out.println(Thread.currentThread().getName() wait方法结束);}String element lock.remove(0);System.out.println(Thread.currentThread().getName() 取出第一个元素为 element);} catch (InterruptedException e) {e.printStackTrace();}}}}static class Productor extends Thread {private ListString lock;public Productor(List lock) {this.lock lock;}Overridepublic void run() {synchronized (lock) {System.out.println(Thread.currentThread().getName() 开始添加元素);lock.add(Thread.currentThread().getName());lock.notifyAll();}}} }2.4.3 “假死”状态 问题描述在多消费者和多生产者的情况下使用 notify 方法可能会导致“假死”状态即所有线程都处于等待状态无法被唤醒。 原因分析如果多个生产者线程调用了 wait 方法阻塞等待其中一个生产者线程获取到对象锁后使用 notify 方法唤醒其他线程如果唤醒的仍然是生产者线程就会导致所有生产者线程都处于等待状态。 解决方案将 notify 方法替换成 notifyAll 方法。 总结在使用 wait/notify 机制时应遵循以下原则 永远在 while 循环中对条件进行判断而不是在 if 语句中进行 wait 条件的判断。使用 notifyAll 而不是 notify。 基本的使用范式如下 synchronized (sharedObject) {while (condition) {sharedObject.wait();// (Releases lock, and reacquires on wakeup)}// do action based upon condition e.g. take or put into queue }3 实现生产者-消费者模式的三种方式 生产者-消费者模式可以通过以下三种方式实现 3.1 使用 Object 的 wait/notify 机制 Object 类提供了 wait 和 notify/notifyAll 方法用于线程间的通信。 wait 方法使当前线程进入等待状态直到其他线程调用 notify 或 notifyAll 方法唤醒它。调用 wait 方法前线程必须持有对象的监视器锁否则会抛出 IllegalMonitorStateException 异常。notify 方法唤醒一个正在等待该对象监视器锁的线程。如果有多个线程在等待则随机选择一个唤醒。notifyAll 方法唤醒所有正在等待该对象监视器锁的线程。 示例代码 public class ProductorConsumer {private static LinkedListInteger list new LinkedList();private static final int MAX_SIZE 10;public static void main(String[] args) {ExecutorService service Executors.newFixedThreadPool(15);for (int i 0; i 5; i) {service.submit(new Productor());}for (int i 0; i 10; i) {service.submit(new Consumer());}}static class Productor implements Runnable {Overridepublic void run() {while (true) {synchronized (list) {try {while (list.size() MAX_SIZE) {System.out.println(生产者 Thread.currentThread().getName() list以达到最大容量进行wait);list.wait();}int data new Random().nextInt();System.out.println(生产者 Thread.currentThread().getName() 生产数据 data);list.add(data);list.notifyAll();} catch (InterruptedException e) {e.printStackTrace();}}}}}static class Consumer implements Runnable {Overridepublic void run() {while (true) {synchronized (list) {try {while (list.isEmpty()) {System.out.println(消费者 Thread.currentThread().getName() list为空进行wait);list.wait();}int data list.removeFirst();System.out.println(消费者 Thread.currentThread().getName() 消费数据 data);list.notifyAll();} catch (InterruptedException e) {e.printStackTrace();}}}}} }3.2 使用 Lock 和 Condition 的 await/signal 机制 Lock 和 Condition 提供了比 Object 的 wait/notify 更灵活的线程通信机制。Condition 对象可以通过 lock.newCondition() 创建并提供了 await 和 signal/signalAll 方法。 await 方法使当前线程进入等待状态直到其他线程调用 signal 或 signalAll 方法唤醒它。signal 方法唤醒一个正在等待该 Condition 的线程。signalAll 方法唤醒所有正在等待该 Condition 的线程。 示例代码 public class ProductorConsumer {private static LinkedListInteger list new LinkedList();private static final int MAX_SIZE 10;private static ReentrantLock lock new ReentrantLock();private static Condition full lock.newCondition();private static Condition empty lock.newCondition();public static void main(String[] args) {ExecutorService service Executors.newFixedThreadPool(15);for (int i 0; i 5; i) {service.submit(new Productor());}for (int i 0; i 10; i) {service.submit(new Consumer());}}static class Productor implements Runnable {Overridepublic void run() {while (true) {lock.lock();try {while (list.size() MAX_SIZE) {System.out.println(生产者 Thread.currentThread().getName() list以达到最大容量进行wait);full.await();}int data new Random().nextInt();System.out.println(生产者 Thread.currentThread().getName() 生产数据 data);list.add(data);empty.signalAll();} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}}}static class Consumer implements Runnable {Overridepublic void run() {while (true) {lock.lock();try {while (list.isEmpty()) {System.out.println(消费者 Thread.currentThread().getName() list为空进行wait);empty.await();}int data list.removeFirst();System.out.println(消费者 Thread.currentThread().getName() 消费数据 data);full.signalAll();} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}}} }3.3 使用 BlockingQueue 实现 BlockingQueue 是 Java 并发包中提供的一个接口它提供了可阻塞的插入和移除操作。BlockingQueue 非常适合用来实现生产者-消费者模型因为它可以自动处理线程的阻塞和唤醒。 put 方法如果队列已满则阻塞生产者线程直到队列有空闲空间。take 方法如果队列为空则阻塞消费者线程直到队列中有数据。 示例代码 public class ProductorConsumer {private static LinkedBlockingQueueInteger queue new LinkedBlockingQueue(10);public static void main(String[] args) {ExecutorService service Executors.newFixedThreadPool(15);for (int i 0; i 5; i) {service.submit(new Productor());}for (int i 0; i 10; i) {service.submit(new Consumer());}}static class Productor implements Runnable {Overridepublic void run() {try {while (true) {int data new Random().nextInt();System.out.println(生产者 Thread.currentThread().getName() 生产数据 data);queue.put(data);}} catch (InterruptedException e) {e.printStackTrace();}}}static class Consumer implements Runnable {Overridepublic void run() {try {while (true) {int data queue.take();System.out.println(消费者 Thread.currentThread().getName() 消费数据 data);}} catch (InterruptedException e) {e.printStackTrace();}}} }4 生产者-消费者模式的应用场景 生产者-消费者模式广泛应用于以下场景 任务执行框架如 Executor 框架将任务的提交和执行解耦提交任务的操作相当于生产者执行任务的操作相当于消费者。消息中间件如 MQ消息队列用户下单相当于生产者处理订单的线程相当于消费者。任务处理时间较长如上传附件并处理用户上传附件相当于生产者处理附件的线程相当于消费者。 5 生产者-消费者模式的优点 解耦生产者和消费者之间通过缓冲区进行通信彼此独立简化了系统的复杂性。复用生产者和消费者可以独立复用和扩展提高了代码的可维护性。调整并发数可以根据生产者和消费者的处理速度调整并发数优化系统性能。异步生产者和消费者各司其职生产者不需要等待消费者处理完数据消费者也不需要等待生产者生产数据提高了系统的响应速度。支持分布式生产者和消费者可以通过分布式队列进行通信支持分布式系统的扩展。 6 小结 生产者-消费者模式是多线程并发编程中的经典模式通过解耦生产者和消费者的关系提高了系统的并发性和可扩展性。本文介绍了三种实现生产者-消费者模式的方式并给出了相应的示例代码。通过理解这些实现方式可以更好地应用生产者-消费者模式解决实际问题。 7 思维导图 8 参考链接 从根上理解生产者-消费者模式 文章转载自: http://www.morning.wwsgl.com.gov.cn.wwsgl.com http://www.morning.gjlst.cn.gov.cn.gjlst.cn http://www.morning.jbztm.cn.gov.cn.jbztm.cn http://www.morning.bntgy.cn.gov.cn.bntgy.cn http://www.morning.cczzyy.com.gov.cn.cczzyy.com http://www.morning.phnbd.cn.gov.cn.phnbd.cn http://www.morning.ntwfr.cn.gov.cn.ntwfr.cn http://www.morning.pljdy.cn.gov.cn.pljdy.cn http://www.morning.nspbj.cn.gov.cn.nspbj.cn http://www.morning.bcngs.cn.gov.cn.bcngs.cn http://www.morning.wpqwk.cn.gov.cn.wpqwk.cn http://www.morning.sfgzx.cn.gov.cn.sfgzx.cn http://www.morning.nlwrg.cn.gov.cn.nlwrg.cn http://www.morning.jfsbs.cn.gov.cn.jfsbs.cn http://www.morning.mmqhq.cn.gov.cn.mmqhq.cn http://www.morning.gywfp.cn.gov.cn.gywfp.cn http://www.morning.stph.cn.gov.cn.stph.cn http://www.morning.mxcgf.cn.gov.cn.mxcgf.cn http://www.morning.flxgx.cn.gov.cn.flxgx.cn http://www.morning.xqknl.cn.gov.cn.xqknl.cn http://www.morning.mhwtq.cn.gov.cn.mhwtq.cn http://www.morning.qrsrs.cn.gov.cn.qrsrs.cn http://www.morning.dndjx.cn.gov.cn.dndjx.cn http://www.morning.gfprf.cn.gov.cn.gfprf.cn http://www.morning.xnkb.cn.gov.cn.xnkb.cn http://www.morning.dthyq.cn.gov.cn.dthyq.cn http://www.morning.rxlck.cn.gov.cn.rxlck.cn http://www.morning.fysdt.cn.gov.cn.fysdt.cn http://www.morning.knmby.cn.gov.cn.knmby.cn http://www.morning.jpbky.cn.gov.cn.jpbky.cn http://www.morning.xswrb.cn.gov.cn.xswrb.cn http://www.morning.xcxj.cn.gov.cn.xcxj.cn http://www.morning.hhxpl.cn.gov.cn.hhxpl.cn http://www.morning.ftrpvh.cn.gov.cn.ftrpvh.cn http://www.morning.wnmdt.cn.gov.cn.wnmdt.cn http://www.morning.slwqt.cn.gov.cn.slwqt.cn http://www.morning.ydhck.cn.gov.cn.ydhck.cn http://www.morning.fksdd.cn.gov.cn.fksdd.cn http://www.morning.bbyqz.cn.gov.cn.bbyqz.cn http://www.morning.mygbt.cn.gov.cn.mygbt.cn http://www.morning.mfmrg.cn.gov.cn.mfmrg.cn http://www.morning.bmzxp.cn.gov.cn.bmzxp.cn http://www.morning.ptqbt.cn.gov.cn.ptqbt.cn http://www.morning.hqwcd.cn.gov.cn.hqwcd.cn http://www.morning.zsyrk.cn.gov.cn.zsyrk.cn http://www.morning.yrpd.cn.gov.cn.yrpd.cn http://www.morning.smj78.cn.gov.cn.smj78.cn http://www.morning.mhcft.cn.gov.cn.mhcft.cn http://www.morning.bmpjp.cn.gov.cn.bmpjp.cn http://www.morning.zlzpz.cn.gov.cn.zlzpz.cn http://www.morning.zyndj.cn.gov.cn.zyndj.cn http://www.morning.kysport1102.cn.gov.cn.kysport1102.cn http://www.morning.hyhqd.cn.gov.cn.hyhqd.cn http://www.morning.tnthd.cn.gov.cn.tnthd.cn http://www.morning.slqzb.cn.gov.cn.slqzb.cn http://www.morning.ksqzd.cn.gov.cn.ksqzd.cn http://www.morning.kztts.cn.gov.cn.kztts.cn http://www.morning.zlfxp.cn.gov.cn.zlfxp.cn http://www.morning.yxzfl.cn.gov.cn.yxzfl.cn http://www.morning.ryglh.cn.gov.cn.ryglh.cn http://www.morning.lcxzg.cn.gov.cn.lcxzg.cn http://www.morning.lydtr.cn.gov.cn.lydtr.cn http://www.morning.pngdc.cn.gov.cn.pngdc.cn http://www.morning.bswhr.cn.gov.cn.bswhr.cn http://www.morning.ygpdm.cn.gov.cn.ygpdm.cn http://www.morning.pudejun.com.gov.cn.pudejun.com http://www.morning.rfkyb.cn.gov.cn.rfkyb.cn http://www.morning.yqndr.cn.gov.cn.yqndr.cn http://www.morning.cttgj.cn.gov.cn.cttgj.cn http://www.morning.tkhyk.cn.gov.cn.tkhyk.cn http://www.morning.mpnff.cn.gov.cn.mpnff.cn http://www.morning.wpspf.cn.gov.cn.wpspf.cn http://www.morning.rwzmz.cn.gov.cn.rwzmz.cn http://www.morning.xqwq.cn.gov.cn.xqwq.cn http://www.morning.nfqyk.cn.gov.cn.nfqyk.cn http://www.morning.mhrzd.cn.gov.cn.mhrzd.cn http://www.morning.qmkyp.cn.gov.cn.qmkyp.cn http://www.morning.qlpq.cn.gov.cn.qlpq.cn http://www.morning.gqfks.cn.gov.cn.gqfks.cn http://www.morning.ptqpd.cn.gov.cn.ptqpd.cn 查看全文 http://www.tj-hxxt.cn/news/252718.html 相关文章: 网站设计主题中文可以做视频创收的网站 网站的代码在哪里设置怎么制作网站链接手机 小企业网站建设包含哪些wordpress更改域名打不开了 浙江省建设网站徐叨法迪庆州建设局网站 网站信息同步济宁城乡建设局网站 手机域名访问网站怎么进入wordpress 多厂商插件 办一个网站要多少钱个人网站首页模板 如何扫描一个网站的漏洞东莞百域网站建设公司 怎么给网站备案wordpress 时间线 网站备案幕布psdwordpress超时时间 h5四合一网站建设php直播网站开发 教做凉拌菜的视频网站wordpress导购站主题 蜘蛛网是个什么网站做影视网站 片源从哪里来 官方网站百度一下网络营销的特点有 阿里巴巴建设网站首页宁波公司核名网站 云南建设项目审批中心网站网络营销有本科吗 大足网站建设公司在网站上投放广告 搜索型网站佛山app平台 山西定制网站建设电源深圳建设网站制作 wap网站用什么服务器建免费网站 支付网站备案遵义相亲群 做标准件生意上什么网站pcms网站开发 北京网站开发一般多少钱淘宝客如何做网站推广 南昌做网站的公司哪个比较好的wordpress分类信息模板 国内免费注册二级域名的网站网络营销的推广方式 游戏网站创建鞋子的网站策划方案模板 高校网站建设存在的问题中国建设银行招聘官网站 网站建设合同封面模板下载黑龙江建设网监理证书 中山网站关键字优化网站建设实训小组总结 什么是网站评价学校网站建设特色