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中支持单继承.不直接支持多继承,但对C++中的多继承机制进行改良. 单继承:一个子类只能有一个直接父类. 多继承:一个子类可以有多个直接父类(java中不允许,进行改良).不直接支持,因为多个 ...
- 关于AOP装饰函数中的this
在学习关于JavaScript的装饰者设计模式的过程中,发现其实现方式的关键在于this的使用. 想象一个匿名函数(其实预定义的有名函数也可以,都存在引用),其中的this: // 我们先定义一个匿名 ...
- Ubuntu软件中心卡在正在应用更改的解决办法
http://forum.ubuntu.org.cn/viewtopic.php?t=374037 http://forum.ubuntu.org.cn/viewtopic.php?p=2743994 ...
- Java基础总结--IO总结2
1.键盘录入--Java具有特定的对象封装这些输入输出设备在System类定义 in-InputStream类型和out-PrintStream类型成员变量阻塞是方法:read()无数据就阻塞wind ...
- 基于vip和twemproxy代理实现redis集群的无感知弹性扩容
目标是实现redis集群的无感知弹性扩容 关键点 1是无感知,即对redis集群的用户来说服务ip和port保持不变 2.弹性扩容,指的是在需要时刻可以按照业务扩大redis存储容量. 最原始的twe ...
- LeetCode 152. Maximum Product Subarray (最大乘积子数组)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- LeetCode 48. Rotate Image(旋转图像)
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- 使用fabric解决百度BMR的spark集群各节点的部署问题
前言 和小伙伴的一起参加的人工智能比赛进入了决赛之后的一段时间里面,一直在构思将数据预处理过程和深度学习这个阶段合并起来.然而在合并这两部分代码的时候,遇到了一些问题,为此还特意写了脚本文件进行处理. ...
- 读书笔记-你不知道的JS中-promise
之前的笔记没保存没掉了,好气,重新写! 填坑-- 现在与将来 在单个JS文件中,程序由许多块组成,这些块有的现在执行,有的将来执行,最常见的块单位是函数. 程序中'将来'执行的部分并不一定在'现在'运 ...
- Java中Double保留后小数位的几种方法
最近做个小实验,其中一部分要求将表单提交的数据转换为double,这个功能其实很简单直接一句Double.parseDouble(request.getParameter("chinese& ...