对这个问题更深一点理解是,每一个线程都在竞争这个类的实例的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. 教程 | Linux常用命令大全

    Linux常用命令 目录操作命令 ls 命令名称:ls 命令英文原意:list 命令所在路径:/bin/ls 执行权限:所有用户 功能描述:显示目录文件 ls (显示当前目录下文件) ls 目录名 ( ...

  2. java 文件相关问题

    1.文件路径 分隔符 System.out.println(File.separator); System.out.println(File.pathSeparator); /*mac os 和 li ...

  3. Ajax案例:异步加载商品分类信息

  4. [软件工程基础]Alpha 展示博客

    团队成员 个人简介 个人简介参照团队介绍博客. 个人博客 王嘉睿爵:http://www.cnblogs.com/whynotRW/ 游心:http://www.cnblogs.com/jefhq/ ...

  5. CentOS,net core2 sdk nginx、supervisor、mysql

    CentOS下 .net core2 sdk nginx.supervisor.mysql环境搭建 作为.neter,看到.net core 2.0的正式发布,心里是有点小激动的,迫不及待的体验了一把 ...

  6. 数据库(数据库、表及表数据、SQL语句)

    数据库MYSQL 今日内容介绍 u MySQL数据库 u SQL语句 第1章 数据库 1.1 数据库概述 l 什么是数据库 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储 ...

  7. God made relatives.Thank God we can choose our friends.

    God made relatives.Thank God we can choose our friends. 神决定了谁是你的亲戚, 幸运的是在选择朋友方面他给了你留了余地

  8. Reset CSS 页面初始化css

    CSS 初始化样式(Reset CSS 官网提供): /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: non ...

  9. 常用css和js组件

    1 . input框中插入图标 <div class="col-sm-12 col-xs-12 setLineHeight"> <div class=" ...

  10. 用配置文件方式启动mongodb集群