1 wait notify
wait/notify:
wait()使线程停止,notify使wait状态的线程继续执行。
wait()是Object类的方法,该方法用来将线程置入“预执行队列”,并在wait()方法处停止执行,直到接到通知或被中断为止。调用wait()方法必须要获得对象的锁,即只能在同步方法或同步块中调用wait()方法。调用wait()方法后,对象的锁被当前线程释放。
notify()也是在同步块或同步方法中调用,调用前必须获得对象的锁,该方法用来通知那些等待该对象的锁的其它线程。如果有多个线程等待,则挑选一个wait()状态线程,对其发出通知,如果没有线程等待,则该命令被忽略。在该notify()方法所在的synchronized块或方法执行完毕后,才使被挑选的线程获取该对象的锁。
注意:如果调用wait() 或notify() 没有持有对象的锁,会抛出IlegalMonitorStateException异常。
package multiMethod.waitNotify; import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; public class MyList {
private List<String> list = new LinkedList<String>();
private AtomicInteger count = new AtomicInteger(0);
private int maxSize, minSize;
private Object lock = new Object(); public MyList(int maxSize, int minSize) {
this.maxSize = maxSize;
this.minSize = minSize;
} public void add() {
synchronized (lock) {
try {
if (getSize() == maxSize) {
lock.wait();
}
} catch (Exception e) {
}
list.add("hello");
System.out.println("add ...");
count.incrementAndGet();
lock.notify();
}
} public void take() {
synchronized (lock) {
try {
if (getSize() <= minSize) {
lock.wait();
}
} catch (Exception e) {
// TODO: handle exception
}
list.remove(count.get()-1);
System.out.println("take().......");
this.count.decrementAndGet();
lock.notify();
}
} public int getSize() {
return count.get();
} public static void main(String[] args) {
MyList queue = new MyList(6, 3);
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
queue.add();
}
}
});
Thread threadB = new Thread(new Runnable() { @Override
public void run() {
while (true) {
queue.take();
}
}
}); Thread threadC = new Thread(new Runnable() { @Override
public void run() {
while (true) {
System.out.println((queue.count));
}
}
}); threadB.start();
threadA.start();
threadC.start();
}
}
每个锁对象有两个队列,一个就绪队列,一个阻塞队列。就绪队列中线程已被唤醒,等待获得cpu,阻塞队列执行了wait(),等待被唤醒。
需要注意的是:
1. notify()通知过早,线程不会被唤醒,因为wait()后于notify()执行。
2. wait等待条件发生了变化,线程也不会被唤醒。
3. 唤醒同类,线程陷入假死。如:生产者唤醒生产者,消费者唤醒消费者。
1 wait notify的更多相关文章
- Thread Object wait() notify()基本
package com.thread.test.thread; import java.util.ArrayDeque; import java.util.Queue; import java.uti ...
- 如何在 Java 中正确使用 wait, notify 和 notifyAll(转)
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...
- java多线程wait notify join
wait notify 几个注意点: wait 与 notify/notifyAll 方法必须在同步代码块中使用,即要先对调用对象加锁. 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进 ...
- 【Java并发系列02】Object的wait()、notify()、notifyAll()方法使用
一.前言 对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多. 二.线程安全基本知识 首先应该记住以下基本点,先背下来也无妨: ...
- 【多线程】java多线程 测试例子 详解wait() sleep() notify() start() join()方法 等
java实现多线程,有两种方法: 1>实现多线程,继承Thread,资源不能共享 2>实现多线程 实现Runnable接口,可以实现资源共享 *wait()方法 在哪个线程中调用 则当前 ...
- #研发中间件介绍#异步消息可靠推送Notify
郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发 电商系统为什么需要 NotifyServer? ...
- 线程同步以及 yield() wait()和notify()、notifyAll()
1.yield() 该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会. 2.wait()和notify().notifyAll() 这 ...
- java 多线程之wait(),notify,notifyAll(),yield()
wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...
- wait、notify、sleep、interrupt对比分析
对比分析Java中的各个线程相关的wait().notify().sleep().interrupt()方法 方法简述 Thread类 sleep:暂停当前正在执行的线程:(类方法) yield:暂停 ...
- java中的wait(),notify(),notifyAll(),synchronized方法
wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...
随机推荐
- Tuple和 ValueTuple
这个类型还是学习C#7.0的语法在看到的,这边单独拿来学习下. 学习地址: https://docs.microsoft.com/zh-cn/dotnet/csharp/tuples https:// ...
- 安装MySQL8.0.13
引用于:CrazyDemo,博客地址:http://www.cnblogs.com/CrazyDemo 下载地址: https://www.mysql.com/downloads/ 现在最下边的社区版 ...
- Redis的数据类型以及各类型的操作
讲完安装和配置,接下来就是所有数据库的重头戏,数据结构和常用操作的增删改查了 redis是key-value的数据结构,每条数据都是⼀个键值对 键的类型是字符串 注意:键不能重复 值的类型分为五种: ...
- 07JavaScript数据类型
JavaScript 数据类型 值类型(基本类型):字符串(String).数字(Number).布尔(Boolean).对空(Null).未定义(Undefined).Symbol. 引用数据类型: ...
- Java分布式锁之数据库方式实现
之前的文章<Java分布式锁实现>中列举了分布式锁的3种实现方式,分别是基于数据库实现,基于缓存实现和基于zookeeper实现.三种实现方式各有可取之处,本篇文章就详细讲解一下Java分 ...
- MVC action过滤器验证登录
方法一 : 1.创建一个全局action过滤器 (在appstart 的filterconfig中注册 filters.Add(new LoginAttribute());) 2.不需要登 ...
- thinkphp5 部署到iis服务器url重写
thinkphp部署到iis服务器配置url重写的解决方法: 1.下载 url rewrite.下载地址:https://www.iis.net/downloads/microsoft/url-rew ...
- .net第三方数据库物理卡号同步功能实现
本地数据库用的是Oracle,第三方数据库是SQL Server,连接字符串保存在web.config里面. 第三方数据库为增量,每次读取要记录读取的最大位置.我是保存在本地txt文件里面. //保存 ...
- usb之鼠标作为按键输入
1. 首先搞清楚,鼠标点左键.右键等能得到什么数据,然后分析这些数据上报事件即可. 第一个基本点:usb_alloc_urb函数,创建一个struct urb结构体,只能使用这个函数来创建,它是urb ...
- [STM32F4][关于看门狗的那些事]
STM32(stm32f4XX系列)看门狗的总结: 1. 具有两个看门狗外设(独立和窗口)均可用于检测并解决由软件错误导致的故障:当计数器达到给定的超时值时,触发一个中断(仅适用于窗口看门狗)或产生一 ...