文档章节

线程通信(生产者与消费者问题)

学而时习之
 学而时习之
发布于 2015/03/11 11:37
字数 800
阅读 388
收藏 6

1、线程通信的必要性

    多线程不仅共享资源,而且相互牵制向前运行。

2、线程通信的方法(都是在Object中定义)

    3个方法:

                1)    wait() 可运行转入阻塞状态,放锁

                2)    notify() 阻塞转入可运行状态,获得锁

                3)    notifyAll() 所有调用wait方法而被挂起的线程重新启动,有个条件:wait与notifyAll必须是属于同一个对象

    必须在同步方法或同步代码块中使用

3、共享资源类(仓库)

    注:共享资源(产品),牵制信息(产品有无)

 package com.ljb.app.communication;
/**
 * 共享资源类
 * @author LJB
 * @version 2015年3月11日
 */
public class ShareData {
 // 产品
 private char c;
 
 // 牵制信息(产品有无,开始时仓库中没有产品)
 private boolean isProduced = false;
 
 /*
  * 放产品(生产产品)
  */
 public synchronized void putShareChar (char c) {
  // 如果消费者还没有消费或者仓库中有产品,则生产者等待
  if (isProduced) {
   System.out.println("消费者还未消费,因此生产者停止生产。");
   try {
    wait();// 生产者等待
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  
  // 仓库中放入生产的产品
  this.c = c;
  
  // 改变信号量(有产品)
  isProduced = true;
  
  // 通知消费者消费
  notify();
  System.out.println("生产者生产了产品" + c + ",通知消费者消费...");
 }
 
 /*
  * 取产品(消费产品)
  */
 public synchronized char getShareChar () {
  // 如果生产者还未生产或者仓库中没有产品,则消费者等待
  if (!isProduced) {
   System.out.println("生产者还未生产,因此消费者停止消费。");
   try {
    wait();// 消费者等待
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  
  // 改变信号量(没有产品或者消费了该产品)
  isProduced = false;
  
  // 通知生产者生产
  notify();
  System.out.println("消费者消费了产品" + c + ",通知生产者生产...");
  
  return this.c;
 }
}

4、生产者线程

 package com.ljb.app.communication;
/**
 * 生产者线程,每隔一段时间生产一个产品
 * @author LJB
 * @version 2015年3月11日
 */
public class Producer extends Thread{
 // 共享资源对象
 private ShareData s;
 
 // 有参构造方法
 public Producer (ShareData s) {
  this.s = s;
 }
 
 public void run () {
  for (char ch = 'A' ; ch <= 'D' ; ch++) {
   try {
    Thread.sleep((int)(Math.random()*3000));
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   s.putShareChar(ch);// 将产品放入仓库
  }
 }
}

5、消费者线程

 package com.ljb.app.communication;
/**
 * 消费者线程
 * @author LJB
 * @version 2015年3月11日
 */
public class Consumer extends Thread{
 // 共享资源
 private ShareData s;
 
 // 构造方法
 public Consumer (ShareData s) {
  this.s = s;
 }
 
 public void run () {
  char ch;
  do {
   try {
    Thread.sleep((int)(Math.random()*3000));
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   ch = s.getShareChar();// 从仓库中取出产品
  } while (ch != 'D');
 }
}

6、测试类

 package com.ljb.app.communication;
/**
 * 测试类
 * @author LJB
 * @version 2015年3月11日
 */
public class Test {
 /**
  * @param args
  */
 public static void main(String[] args) {
  ShareData s = new ShareData();
  
  Thread consumer = new Consumer(s);
  consumer.start();
  
  Thread producer = new Producer(s);
  producer.start();
 }
}

运行结果:

生产者还未生产,因此消费者停止消费。
生产者生产了产品A,通知消费者消费...
消费者消费了产品A,通知生产者生产...
生产者生产了产品B,通知消费者消费...
消费者消费了产品B,通知生产者生产...
生产者生产了产品C,通知消费者消费...
消费者消费了产品C,通知生产者生产...
生产者生产了产品D,通知消费者消费...
消费者消费了产品D,通知生产者生产...

© 著作权归作者所有

上一篇: 网络编程基础
下一篇: 死锁
学而时习之
粉丝 30
博文 93
码字总数 42877
作品 0
西安
私信 提问
生产者—消费者模型

生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。 这里实现如下情况的生产--消费模型: 生产者不断交替...

architect刘源源
2018/01/30
0
0
如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。 在 Java 中可以用 wait、notify 和 ...

牧师-Panda
2016/10/20
21
0
生产者消费者问题理解与Java实现

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程—...

hanzhankang
2014/01/17
0
0
多线程(三)

多线程间的通信 本文继续接着讲解多线程,这儿会涉及到多线程的高级部分——多线程间的通信。 多线程间的通信其实就是多个线程都在处理同一个资源,但是处理的任务却不一样。最经典的案例就是...

yerenyuan_pku
2017/10/08
0
0
Java synchronized 使用

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程—...

jiangmitiao
2015/06/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

硬件配置

https://akkadia.org/drepper/futex.pdf sudo lshw -businfo[sudo] lambda 的密码: Bus info Device Class Description======================================......

MtrS
今天
2
0
springmvc的return “success”源码解读

qqqq

architect刘源源
今天
5
0
Java程序员五面阿里分享 逆袭成功 太不容易了!

前言 拿到阿里实习offer,经历了5次面试,其中4轮技术面,1轮HR面试。在这里分享一下自己的面试经验和学习心得。希望能够帮助更多的小伙伴。 我本科毕业于中南大学信管专业,真正开始学习Jav...

别打我会飞
昨天
4
0
Android Camera模块解析之视频录制

《Android Camera架构》 《Android Camera进程间通信类总结》 《Android Camera模块解析之拍照》 《Android Camera模块解析之视频录制》 《Android Camera原理之CameraDeviceCallbacks回调模...

天王盖地虎626
昨天
2
0
手把手教你使用issue作为博客评论系统

自从上周在阮一峰的 每周分享第 60 期 看到了可以将 GitHub 的 issue 当作评论系统,插入第三方网页的 JS 库——utterances。我就对此“魂牵梦绕”。个人博客使用的是VuePress。 TLDR (不多废...

jump--jump
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部