线程间通信,生产者消费者问题!
来源:互联网 发布:cf无后坐力软件 编辑:程序博客网 时间:2024/05/29 16:35
线程之间的通信简介:
一般而言,在一个应用程序中(即进程),一个线程往往不是孤立存在的,常常需要和其它线程通信,以执行特定的任务。如主线程和次线程,次线程与次线程,工作线程和用户界面线程等。这样,线程与线程间必定有一个信息传递的渠道。这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的。
线程通信的目标是使线程间能够互相发送信号。另一方面,线程通信使线程能够等待其他线程的信号。
例如,线程B可以等待线程A的一个信号,这个信号会通知线程B数据已经准备好了,典型的例子就是生产者消费者问题,生产者生产了一定量的产品,消费者这边才拥有商品出售。本文将通过JAVA线程间通信来实现生产者与消费者问题,在此之前我们需要了解一下几个知识点:
1、通过共享对象通信(产品)
2、忙等待
3、wait(),notify()和notifyAll()
4、多线程等待相同信号
1.线程间通信的共享对象(Product)
Product类是生产者与消费者的共享类,是实现他们之间数据的共享对象。生产者生产Product,消费者消费Product,所以在Product类中,分别有一个make和一个sale方法。注意,在这两个方法中,都使用了synchronized关键字,实现线程安全机制。在每个方法中,还用到了wait和notify方法, Obj.wait(),与Obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,与notify是针对已经获取了Obj锁进行操作,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内。从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。
具体代码如下:
<span style="font-size:18px;">import java.util.ArrayList;import java.util.List;public class Product {private String name;private int count;public static List<Product> list = new ArrayList<Product>();public String getName() {return name;}public void setName(String name) {this.name = name;}public int getCount() {return list.size();}public void setCount(int count) {this.count = count;}public static List<Product> getList() {return list;}public static void setList(List<Product> list) {Product.list = list;}// /生产方法public synchronized void make(Product p) {if (getCount() > 9) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {this.notifyAll();list.add(p);}}// /消费public synchronized void sale() {if (getCount() < 1) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {this.notifyAll();list.remove(0);}}}</span>
2.生产者类,生产者类实现了Runnable接口,所以是一个线程类。源码如下:
<span style="font-size:18px;">public class Maker implements Runnable {Product product = new Product();public Maker(Product product) {this.product = product;}public void run() {while (true) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}Product p = new Product();p.setName("aaa");product.make(p);System.out.println("生产:当前剩余产品-->" + product.getCount());}}}</span>
3.消费者类,消费者类也实现了Runnable接口。
<span style="font-size:18px;">public class Saler implements Runnable {Product product = new Product();public Saler(Product product) {this.product = product;}public void run() {while (true) {try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}product.sale();System.out.println("消费:当前剩余产品-->" + product.getCount());}}}</span>
<span style="font-size:18px;">public class Test {public static void main(String[] args) {Product product = new Product();Maker maker = new Maker(product);Saler saler = new Saler(product);Thread m1 = new Thread(maker);Thread m2 = new Thread(maker);Thread m3 = new Thread(maker);Thread m4 = new Thread(maker);Thread s1 = new Thread(saler);Thread s2 = new Thread(saler);m1.start();m2.start();m3.start();m4.start();s1.start();s2.start();}}</span>
5.运行结果如果下,运行结果中我们可以看到,生产者生产商品的数量,不会超过10个,当商品数量超过10个的时候,生产者就会停止生产,而是等待消费者消费了一定量的商品,才会继续生产。同样,当剩余商品的数量小于0时,消费者也不会继续消费。这就实现了生产者与消费者间的线程通信,两者共享一个数据对象。
0 0
- 线程间通信,生产者消费者问题!
- 线程间通信之生产者消费者问题
- 线程间通信(生产者消费者问题)
- 线程间通信(生产者与消费者问题)
- 线程间通信-生产者消费者
- java基础12:线程间通信---生产者消费者问题
- 线程间通信-多生产者多消费者问题
- 线程间通信--多生产者多消费者问题
- Java线程间的相互通信--生产者消费者问题
- Java线程间通信问题分析(生产者消费者模型)
- java 线程间通信,多生产者多消费者问题
- 线程通信,生产者消费者问题(Java)
- java线程通信--生产者消费者问题
- JAVA 线程间通信 - 生产者与消费者
- JAVA 线程间通信 - 生产者与消费者
- java线程间通信:生产者--消费者
- 线程间的通信(生产者与消费者)
- 线程间通信-多生产者多消费者
- jQury 基本原理
- Oracle 11g 如何创建数据库
- 结婚个精光换句话黄金价格合计
- mongodb的环境搭建
- CSS布局:div高度随窗口变化而变化
- 线程间通信,生产者消费者问题!
- 迅雷2014校招编程题
- iOS开发之文件管理
- HDU 3651 A Simple Problem (DP 记忆化搜索 或者 bfs)
- 用CryptoAPI实现DES加密解密
- 单例模式
- Pascal's Triangle
- 判断一棵二叉查找树是否是平衡树
- java 反射