Java 多线程同步生产者消费者问题-monitor
对这个问题更深一点理解是,每一个线程都在竞争这个类的实例的monitor对象。
java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods )被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。
任何时刻,对一个指定object对象的某同步方法只能由一个线程来调用。java对象的monitor是跟随object实例来使用的,而不是跟随程序代码。两个线程可以同时执行相同的同步方法,比如:一个类的同步方法是xMethod(),有a,b两个对象实例,一个线程执行a.xMethod(),另一个线程执行b.xMethod(). 互不冲突。下面是单生产者单消费者的实例
/*
* 生产者消费者
* 分类:
* 单生产者单消费者
* 多生产者的消费者
*
*
* 单生产者单消费者:
* 两个线程:生产线程,消费线程
* 两个任务:生产任务,消费任务
* 一份数据
*/
public class Demo4 {
public static void main(String[] args) {
//1.准备数据
Product product = new Product();
//2.创建生产消费任务
Producer producer = new Producer(product);
Consumer consumer = new Consumer(product);
//3.创建生产消费线程
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
//4.开启线程
thread1.start();
thread2.start();
}
} //数据类
class Product{
String name;
double price;
int count; //标识
boolean flag; //准备生产
public synchronized void setProduce(String name,double price) {
if (flag == true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} this.name = name;
this.price = price; System.out.println(Thread.currentThread().getName()+" 生产了:"+name+" 产品的数量:"+count+" 产品的价格:"+price); count++; flag = !flag; //唤醒消费线程
notify();
}
//准备消费
public synchronized void consume() {
if (flag == false) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} System.out.println(Thread.currentThread().getName()+" 消费了:"+name+" 产品的数量:"+count+" 产品的价格:"+price); flag = !flag; //唤醒生产线程
notify();
}
}
//生产任务
class Producer implements Runnable{
Product product; public Producer(Product product) {
super();
this.product = product;
} public void run() {
while (true) {
product.setProduce("bingbing", 10);
}
}
}
//消费任务 class Consumer implements Runnable{
Product product; public Consumer(Product product) {
super();
this.product = product;
} public void run() {
while (true) {
product.consume();
}
}
}
生产者消
多生产者多消费者:
* 两个生产线程,两个消费线程
* 两个任务:生产任务,消费任务
* 一份数据
*
* 生产任务与消费任务共用一个数据--产品类
*
* 要求:最终也要实现一次生产一次消费
*
*错误描述:当有两个生产线程,两个消费线程同时存在的时候,有可能出现生产一次,消费多次或者生产多次消费一次的情况.
*原因:当线程被重新唤醒之后,没有判断标记,直接执行了下面的代码
*
*解决办法:将标记处的if改成while
*
*问题描述:继续运行程序,会出现死锁的情况(4个线程同时处于等待状态)
*原因:唤醒的是本方的线程,最后导致所有的线程都处于等待状态.
*
*解决办法:将notify改成notifyAll.保证将对方的线程唤醒
*
*死锁:出现的情况有两种
*1.所有的线程处于等待状态
*2.锁之间进行嵌套调用
*
*/
public class Demo5 {
public static void main(String[] args) {
//1.准备数据
Product1 product = new Product1();
//2.创建生产消费任务
Producer1 producer = new Producer1(product);
Consumer1 consumer = new Consumer1(product);
//3.创建生产消费线程
Thread thread0 = new Thread(producer);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
Thread thread3 = new Thread(consumer);
//4.开启线程
thread0.start();
thread1.start();
thread2.start();
thread3.start();
}
}
//数据类
class Product1{
String name;
double price;
int count;
//标识
boolean flag;
//准备生产
public synchronized void setProduce(String name,double price) {
while (flag == true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name;
this.price = price;
System.out.println(Thread.currentThread().getName()+" 生产了:"+name+" 产品的数量:"+count+" 产品的价格:"+price);
count++;
flag = !flag;
//唤醒消费线程
//notify();
notifyAll();
}
//准备消费
public synchronized void consume() {
while (flag == false) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" 消费了:"+name+" 产品的数量:"+count+" 产品的价格:"+price);
flag = !flag;
//唤醒生产线程
//notify();
notifyAll();
}
}
//生产任务
class Producer1 implements Runnable{
Product1 product;
public Producer1(Product1 product) {
super();
this.product = product;
}
public void run() {
while (true) {
product.setProduce("bingbing", 10);
}
}
}
//消费任务
class Consumer1 implements Runnable{
Product1 product;
public Consumer1(Product1 product) {
super();
this.product = product;
}
public void run() {
while (true) {
product.consume();
}
}
}
Java 多线程同步生产者消费者问题-monitor的更多相关文章
- Java多线程同步——生产者消费者问题
这是马士兵老师的Java视频教程里的一个生产者消费者问题的模型 public class ProduceConsumer{ public static void main(String[] args) ...
- java多线程解决生产者消费者问题
import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...
- java多线程模拟生产者消费者问题,公司面试常常问的题。。。
package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...
- Java多线程_生产者消费者模式2
在我的上一条博客中,已经介绍到了多线程的经典案列——生产者消费者模式,但是在上篇中用的是传统的麻烦的非阻塞队列实现的.在这篇博客中我将介绍另一种方式就是:用阻塞队列完成生产者消费者模式,可以使用多种阻 ...
- JAVA多线程之生产者 消费者模式 妈妈做面包案例
创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包 最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...
- 【多线程】java多线程实现生产者消费者模式
思考问题: 1.为什么用wait()+notify()实现生产者消费者模式? wait()方法可以暂停线程,并释放对象锁 notify()方法可以唤醒需要该对象锁的其他线程,并在执行完后续步骤,到了s ...
- Java多线程之生产者消费者问题<一>:使用synchronized keyword解决生产者消费者问题
今天看了一片博文,讲Java多线程之线程的协作,当中作者用程序实例说明了生产者和消费者问题,但我及其它读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的样例也都存在bug,经过细致研究发现当中的问 ...
- Java多线程实现生产者消费者延伸问题
在操作系统中有一类问题被称为生产者消费者问题:意为,有数个生产者生产产品,有数个消费者消费产品,他们共享一定数量的缓存. 这里用java多线程编程,实现生产者消费者问题的一种延伸,橘子苹果问题. 题目 ...
- Java多线程-----实现生产者消费者模式的几种方式
1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理 ...
随机推荐
- .Net WebApi接口Swagger集成简单使用
Swagger介绍 Swagger 是一款RESTFUL接口的.基于YAML.JSON语言的文档在线自动生成.代码自动生成的工具.而我最近做的项目用的是WebAPI,前后端完全分离,这时后端使用Swa ...
- excel 公式2列合并
=A2&"="&C2 ="UPDATE comm_department SET parent_id='"&D2&"' ...
- STP-13-MST和其它STP版本的互操作性(没写完)
为了理解MST和其他STP版本的互操作性,首先要来看看MST与没有每VLAN概念的纯IEEE802.1D STP或802.1w RSTP非MST交换机(本书称其为非MST交换机)之间互操作的方式.这些 ...
- [LOJ 2190] 「SHOI2014」信号增幅仪
[LOJ 2190] 「SHOI2014」信号增幅仪 链接 链接 题解 坐标系直到 \(x\) 轴与椭圆长轴平行 点的坐标变换用旋转公式就可以了 因为是椭圆,所以所有点横坐标除以 \(p\) 然后最小 ...
- CodeForces - 1004A-Sonya and Hotels(思维)
Sonya decided that having her own hotel business is the best way of earning money because she can pr ...
- element-ui关于form表单在dialog中的重置
form表单的重置是以第一次打开的数据作为重置标准,如果先打开的是更新,那么重置之后以第一次更新的数据作为标准; Dialog 中的内容是懒加载的,目前 edit (更新)方法的写法导致 Form 刚 ...
- NET Core & Entity Framework Core
ABP 教程文档 1-1 手把手引进门之 ASP.NET Core & Entity Framework Core(官方教程翻译版 版本3.2.5) 本文是ABP官方文档翻译版,翻译基于 ...
- Django使用网站图标
默认情况下,浏览器访问一个网站的时候,同时还会向服务器请求“/favicon.ico”这个URL,目的是获取网站的图标. 若是没有配置的话,Django就会返回一个404错误,并且浏览器接收到这个40 ...
- Hadoop实战项目:小文件合并
项目背景 在实际项目中,输入数据往往是由许多小文件组成,这里的小文件是指小于HDFS系统Block大小的文件(默认128M),早期的版本所定义的小文件是64M,这里的hadoop-2.2.0所定义的小 ...
- Kendo MVVM (二) ObservableObject 对象
概述 Kendo MVVM 框架关键的一个部分为 ViewModel,它主要是通过 kendo.data.ObserableObject 来提供支持的.它可以监控改变( UI 变化或是值的变化)并通知 ...