对这个问题更深一点理解是,每一个线程都在竞争这个类的实例的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的更多相关文章

  1. Java多线程同步——生产者消费者问题

    这是马士兵老师的Java视频教程里的一个生产者消费者问题的模型 public class ProduceConsumer{ public static void main(String[] args) ...

  2. java多线程解决生产者消费者问题

    import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...

  3. java多线程模拟生产者消费者问题,公司面试常常问的题。。。

    package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...

  4. Java多线程_生产者消费者模式2

    在我的上一条博客中,已经介绍到了多线程的经典案列——生产者消费者模式,但是在上篇中用的是传统的麻烦的非阻塞队列实现的.在这篇博客中我将介绍另一种方式就是:用阻塞队列完成生产者消费者模式,可以使用多种阻 ...

  5. JAVA多线程之生产者 消费者模式 妈妈做面包案例

    创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包  最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...

  6. 【多线程】java多线程实现生产者消费者模式

    思考问题: 1.为什么用wait()+notify()实现生产者消费者模式? wait()方法可以暂停线程,并释放对象锁 notify()方法可以唤醒需要该对象锁的其他线程,并在执行完后续步骤,到了s ...

  7. Java多线程之生产者消费者问题<一>:使用synchronized keyword解决生产者消费者问题

    今天看了一片博文,讲Java多线程之线程的协作,当中作者用程序实例说明了生产者和消费者问题,但我及其它读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的样例也都存在bug,经过细致研究发现当中的问 ...

  8. Java多线程实现生产者消费者延伸问题

    在操作系统中有一类问题被称为生产者消费者问题:意为,有数个生产者生产产品,有数个消费者消费产品,他们共享一定数量的缓存. 这里用java多线程编程,实现生产者消费者问题的一种延伸,橘子苹果问题. 题目 ...

  9. Java多线程-----实现生产者消费者模式的几种方式

       1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理 ...

随机推荐

  1. F-三生三世

    链接:https://ac.nowcoder.com/acm/contest/892/F 题意: 秦皇岛的海风轻轻地唱着歌唤醒了水上的涟漪,冬日的阳光把沙滩洒满了金黄. BD哥在沙滩上留下了一串串脚印 ...

  2. codeforces597C-树状数组优化dp

    因为整个序列为一个1-n的排列,所以可以这样dp dp[i][j]代表长度为i,以数字j结尾的子序列 dp[i][j]=dp[i-1][1,2,3...j-1]; 这道题的答案就是 dp[k+1][1 ...

  3. NET Core 开发环境

    NET Core 开发环境 最近,一直在往.Net Core上迁移,随着工作的深入,发现.Net Core比.Net Framework好玩多了.不过目前还在windows下开发,虽然VisualSt ...

  4. RL_RTX函数

    1 延时:os_itv_set(usFrequency) //设置延时周期,配合os_itv_wait使用:os_itv_wait() 是绝对延迟是包含调用前的时间, os_dly_wait() 是相 ...

  5. Mysql修改server uuid

    在主从复制的时候如果第二个虚拟机是复制过去的,需要修改 https://blog.csdn.net/pratise/article/details/80413198 1. 首先要查找到mysql的安装 ...

  6. 【转】Maven项目中将配置文件打包到jar包中

    参考博客:http://blog.csdn.net/ciedecem/article/details/10382275 问题: 项目中需要用到从文件中加载json数据,如图放在conf目录下. 程序中 ...

  7. spring data jpa封装specification实现简单风格的动态查询

    github:https://github.com/peterowang/spring-data-jpa-demo 单一实体的动态查询: @Servicepublic class AdvancedUs ...

  8. ECShop怎么首页调用文章列表

    举例如首页调用方法:1.先打开index.php文件找到以下代码:$smarty->assign('new_articles', index_get_new_articles()); // 最新 ...

  9. 【Unity3D】点击交互——简单工厂

    实现一个很简单的点击小游戏,学习交互相关的内容,在不实时创建销毁的情况下,使用简单工厂创建.管理.回收.复用标记. 游戏概述:点击出现标记,两秒内自动消失 游戏展示: 1.1实现点击效果. 1.1.1 ...

  10. Css Hack 大全(IE6、IE7、IE8、IE9 css hack)

    一.IE6 css hack: 1. *html Selector {} /* Selector 表示 css选择器 下同 */ 2. Selector { _property: value; } / ...