Java多线程学习之wait、notify/notifyAll 详解
public class K {
//状态锁
private Object lock;
//条件变量
private int now,need;
public void produce(int num){
//同步
synchronized (lock){
//当前有的不满足需要,进行等待,直到满足条件
while(now < need){
try {
//等待阻塞
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我被唤醒了!");
}
// 做其他的事情
}
}
}

import java.util.LinkedList; /**
* 生产者和消费者的问题
* wait、notify/notifyAll() 实现
*/
public class Storage1 implements AbstractStorage {
//仓库最大容量
private final int MAX_SIZE = 100;
//仓库存储的载体
private LinkedList list = new LinkedList(); //生产产品
public void produce(int num){
//同步
synchronized (list){
//仓库剩余的容量不足以存放即将要生产的数量,暂停生产
while(list.size()+num > MAX_SIZE){
System.out.println("【要生产的产品数量】:" + num + "\t【库存量】:"
+ list.size() + "\t暂时不能执行生产任务!"); try {
//条件不满足,生产阻塞
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} for(int i=0;i<num;i++){
list.add(new Object());
} System.out.println("【已经生产产品数】:" + num + "\t【现仓储量为】:" + list.size()); list.notifyAll();
}
} //消费产品
public void consume(int num){
synchronized (list){ //不满足消费条件
while(num > list.size()){
System.out.println("【要消费的产品数量】:" + num + "\t【库存量】:"
+ list.size() + "\t暂时不能执行生产任务!"); try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} //消费条件满足,开始消费
for(int i=0;i<num;i++){
list.remove();
} System.out.println("【已经消费产品数】:" + num + "\t【现仓储量为】:" + list.size()); list.notifyAll();
}
}
}
- 抽象仓库类
public interface AbstractStorage {
void consume(int num);
void produce(int num);
}
- 生产者
public class Producer extends Thread{
//每次生产的数量
private int num ;
//所属的仓库
public AbstractStorage abstractStorage;
public Producer(AbstractStorage abstractStorage){
this.abstractStorage = abstractStorage;
}
public void setNum(int num){
this.num = num;
}
// 线程run函数
@Override
public void run()
{
produce(num);
}
// 调用仓库Storage的生产函数
public void produce(int num)
{
abstractStorage.produce(num);
}
}
- 消费者
public class Consumer extends Thread{
// 每次消费的产品数量
private int num;
// 所在放置的仓库
private AbstractStorage abstractStorage1;
// 构造函数,设置仓库
public Consumer(AbstractStorage abstractStorage1)
{
this.abstractStorage1 = abstractStorage1;
}
// 线程run函数
public void run()
{
consume(num);
}
// 调用仓库Storage的生产函数
public void consume(int num)
{
abstractStorage1.consume(num);
}
public void setNum(int num){
this.num = num;
}
}
- 测试
public class Test{
public static void main(String[] args) {
// 仓库对象
AbstractStorage abstractStorage = new Storage1();
// 生产者对象
Producer p1 = new Producer(abstractStorage);
Producer p2 = new Producer(abstractStorage);
Producer p3 = new Producer(abstractStorage);
Producer p4 = new Producer(abstractStorage);
Producer p5 = new Producer(abstractStorage);
Producer p6 = new Producer(abstractStorage);
Producer p7 = new Producer(abstractStorage);
// 消费者对象
Consumer c1 = new Consumer(abstractStorage);
Consumer c2 = new Consumer(abstractStorage);
Consumer c3 = new Consumer(abstractStorage);
// 设置生产者产品生产数量
p1.setNum(10);
p2.setNum(10);
p3.setNum(10);
p4.setNum(10);
p5.setNum(10);
p6.setNum(10);
p7.setNum(80);
// 设置消费者产品消费数量
c1.setNum(50);
c2.setNum(20);
c3.setNum(30);
// 线程开始执行
c1.start();
c2.start();
c3.start();
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
p6.start();
p7.start();
}
}
- 输出
【要消费的产品数量】:50 【库存量】:0 暂时不能执行生产任务!
【要消费的产品数量】:20 【库存量】:0 暂时不能执行生产任务!
【要消费的产品数量】:30 【库存量】:0 暂时不能执行生产任务!
【已经生产产品数】:10 【现仓储量为】:10
【要消费的产品数量】:30 【库存量】:10 暂时不能执行生产任务!
【要消费的产品数量】:20 【库存量】:10 暂时不能执行生产任务!
【要消费的产品数量】:50 【库存量】:10 暂时不能执行生产任务!
【已经生产产品数】:10 【现仓储量为】:20
【已经生产产品数】:10 【现仓储量为】:30
【要消费的产品数量】:50 【库存量】:30 暂时不能执行生产任务!
【已经消费产品数】:20 【现仓储量为】:10
【要消费的产品数量】:30 【库存量】:10 暂时不能执行生产任务!
【已经生产产品数】:10 【现仓储量为】:20
【要消费的产品数量】:50 【库存量】:20 暂时不能执行生产任务!
【要消费的产品数量】:30 【库存量】:20 暂时不能执行生产任务!
【已经生产产品数】:10 【现仓储量为】:30
【已经消费产品数】:30 【现仓储量为】:0
【要消费的产品数量】:50 【库存量】:0 暂时不能执行生产任务!
【已经生产产品数】:10 【现仓储量为】:10
【要消费的产品数量】:50 【库存量】:10 暂时不能执行生产任务!
【已经生产产品数】:80 【现仓储量为】:90
【已经消费产品数】:50 【现仓储量为】:40
Java多线程学习之wait、notify/notifyAll 详解的更多相关文章
- Java多线程学习之Lock与ReentranLock详解
synchronized 是内置锁,而Lock 接口定义的是显示锁,Lock 提供了一种可重入的.可轮询的.定时的以及可中断的锁获取操作. ReenTranLock实现了Lock接口,并提供了与syn ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Java多线程编程中Future模式的详解<转>
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- java多线程的wait、notify/notifyAll区别
1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写. 2.wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized ...
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...
- Java多线程(三)—— synchronized关键字详解
一.多线程的同步 1.为什么要引入同步机制 在多线程环境中,可能会有两个甚至更多的线程试图同时访问一个有限的资源.必须对这种潜在资源冲突进行预防. 解决方法:在线程使用一个资源时为其加锁即可. 访问资 ...
- java 多线程中的wait方法的详解
java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...
- Java多线程之wait、notify/notifyAll 详解,用wait 和notifyAll 以及synchronized实现阻塞队列,多线程拓展之ReentrantLock与Condition
前言:这几天看了很多关于多线程的知识,分享一波.(但是目前接触的项目还未用到过,最多用过线程池,想看线程池 请看我之前的博客) 关于基本的理论等 参考如下: https://www.cnblogs.c ...
- Java再学习——sleep(), wait(), notify(), notifyAll()
首先一点就是Thread.sleep(long millis)方法是Thread类的静态方法,其他三个wait(), notify()和notifyAll()都是Object类的方法. sleep(l ...
随机推荐
- 浅谈Java多态
什么是Java中的多态?又是一个纸老虎的概念,老套路,把它具体化,细分化,先想三个问题(注意,这里不是简单的化整为零,而是要建立在学习一个新概念时的思考框架): 1.这个东西有什么用?用来干什么的?它 ...
- MVVM -- CallMethodAction 和 InvokeCommandAction
MVVM实践教程 算算,从事Silverlight和WPF的开发也有1年多的时间了,虽然时间不算长,虽然还没有突出的成就,但是感觉也还算一般. 但是,从头至今都没有去认真研究和使用过MVVM,虽然 ...
- Echarts数据可视化parallel平行坐标系,开发全解+完美注释
全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...
- linux udev、mdev 介绍
Udev介绍 Udev的下载网址:http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev/ Udev分为三个子计划:namedev,libs ...
- python的re正则表达
正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达式.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE),是计算机科学的一个概念.正则表 ...
- 在CUDA8.0下编译安装OpenCV3.1.0来实现GPU加速(Compiling OpenCV3.1.0 with CUDA8.0 support)
在CUDA8.0下编译安装OpenCV3.1.0 一.本人电脑配置:ubuntu 14.04, NVIDIA GTX1060. 二.编译OpenCV3.1.0前,读者需要成功安装CUDA8.0(网上有 ...
- C#用到windows 消息列表Message类MSG的id代号
C# Constants:private const UInt32 WM_ACTIVATE = 0x0006;private const UInt32 WM_ACTIVATEAPP = 0x001C; ...
- C++内联函数(03)
在C++中我们通常定义以下函数来求两个整数的最大值: 代码如下: int max(int a, int b){ return a > b ? a : b;} 为这么一个小的操作定义一个函数的好处 ...
- Yii2之mailer的使用
Mailer组件是yii框架自带的用于收发邮件的组件,无需安装,只需做一些配置即可使用,非常便捷.本文就mailer组件从配置到使用进行简单讲解. 首先在config/main.php配置如下: ...
- PHP异常处理机制
1. 异常: 异常(Exception)用于在指定的错误发生时改变脚本的正常流程. 当异常被触发时,通常会发生: (1)当前代码状态被保存: (2)代码执行被切换到预定义的异常处理器函数: (3)根据 ...