多线程中wait和notify的理解与使用
1.对于wait()和notify()的理解
对于wait()和notify()的理解,还是要从jdk官方文档中开始,在Object类方法中有:
void notify()
Wakes up a single thread that is waiting on this object’s monitor.
译:唤醒在此对象监视器上等待的单个线程void notifyAll()
Wakes up all threads that are waiting on this object’s monitor.
译:唤醒在此对象监视器上等待的所有线程void wait( )
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll( ) method for this object.
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法void wait(long timeout)
Causes the current thread to wait until either another thread invokes the notify( ) method or the notifyAll( ) method for this object, or a specified amount of time has elapsed.
译:导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。void wait(long timeout, int nanos)
Causes the current thread to wait until another thread invokes the notify( ) method or the notifyAll( ) method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法,或者其他线程打断了当前线程,或者指定的时间过完。
上面是官方文档的简介,下面我们根据官方文档总结一下:
wait( ),notify( ),notifyAll( )都不属于Thread类,而是属于Object基础类,也就是每个对象都有wait( ),notify( ),notifyAll( ) 的功能,因为每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了。
当需要调用以上的方法的时候,一定要对竞争资源进行加锁,如果不加锁的话,则会报 IllegalMonitorStateException 异常
当想要调用wait( )进行线程等待时,必须要取得这个锁对象的控制权(对象监视器),一般是放到synchronized(obj)代码中。
在while循环里而不是if语句下使用wait,这样,会在线程暂停恢复后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知
调用obj.wait( )释放了obj的锁,否则其他线程也无法获得obj的锁,也就无法在synchronized(obj){ obj.notify() } 代码段内唤醒A。
notify( )方法只会通知等待队列中的第一个相关线程(不会通知优先级比较高的线程)
notifyAll( )通知所有等待该竞争资源的线程(也不会按照线程的优先级来执行)
假设有三个线程执行了obj.wait( ),那么obj.notifyAll( )则能全部唤醒tread1,thread2,thread3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,tread1,thread2,thread3只有一个有机会获得锁继续执行,例如tread1,其余的需要等待thread1释放obj锁之后才能继续执行。
当调用obj.notify/notifyAll后,调用线程依旧持有obj锁,因此,thread1,thread2,thread3虽被唤醒,但是仍无法获得obj锁。直到调用线程退出synchronized块,释放obj锁后,thread1,thread2,thread3中的一个才有机会获得锁继续执行。
2.wait和notify简单使用示例
public class WaitNotifyTest {
// 在多线程间共享的对象上使用wait
private String[] shareObj = { "true" };
public static void main(String[] args) {
WaitNotifyTest test = new WaitNotifyTest();
ThreadWait threadWait1 = test.new ThreadWait("wait thread1");
threadWait1.setPriority(2);
ThreadWait threadWait2 = test.new ThreadWait("wait thread2");
threadWait2.setPriority(3);
ThreadWait threadWait3 = test.new ThreadWait("wait thread3");
threadWait3.setPriority(4);
ThreadNotify threadNotify = test.new ThreadNotify("notify thread");
threadNotify.start();
threadWait1.start();
threadWait2.start();
threadWait3.start();
}
class ThreadWait extends Thread {
public ThreadWait(String name){
super(name);
}
public void run() {
synchronized (shareObj) {
while ("true".equals(shareObj[0])) {
System.out.println("线程"+ this.getName() + "开始等待");
long startTime = System.currentTimeMillis();
try {
shareObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("线程" + this.getName()
+ "等待时间为:" + (endTime - startTime));
}
}
System.out.println("线程" + getName() + "等待结束");
}
}
class ThreadNotify extends Thread {
public ThreadNotify(String name){
super(name);
}
public void run() {
try {
// 给等待线程等待时间
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (shareObj) {
System.out.println("线程" + this.getName() + "开始准备通知");
shareObj[0] = "false";
shareObj.notifyAll();
System.out.println("线程" + this.getName() + "通知结束");
}
System.out.println("线程" + this.getName() + "运行结束");
}
}
}
运行结果:
线程wait thread1开始等待
线程wait thread3开始等待
线程wait thread2开始等待
线程notify thread开始准备通知
线程notify thread通知结束
线程notify thread运行结束
线程wait thread2等待时间为:2998
线程wait thread2等待结束
线程wait thread3等待时间为:2998
线程wait thread3等待结束
线程wait thread1等待时间为:3000
线程wait thread1等待结束多线程中wait和notify的理解与使用的更多相关文章
- 多线程中wait、notify理解
实在惭愧,java开发多年,多线程运用一直不多,该知识点理解也不够,不怎么会用.赶上使用多线程 生产者.消费者模式,学习下该知识点. synchronized 获取锁 wait 阻塞本线程,释放对象 ...
- Java多线程中的wait/notify通信模式
前言 最近在看一些JUC下的源码,更加意识到想要学好Java多线程,基础是关键,比如想要学好ReentranLock源码,就得掌握好AQS源码,而AQS源码中又有很多Java多线程经典的一些应用:再比 ...
- 多线程中Object的wait(),notify()和Condition的wait()和singal()对锁的关联
通常将共享资源的操作放置在Sysnchronized定义的区域内,这样当其他线程也获取到这个锁时,必须的等待锁被释放时才能进入该区域.Object为任意一个对象,每个对象都存在一个标志位,并具有两个值 ...
- java多线程中wait/notify/sleep/join/yield方法以及多线程的六种状态
刚开始学线程的时候也是被这几个方法搞的云里雾里的,尤其是一开始看的毕老师的视频,老师一直在强调执行权和执行资格,看的有点懵逼,当然不是说毕老师讲的不好,就是自己有点没听明白,后来复习看了一些其他的博客 ...
- Java线程和多线程(二)——对象中的wait,notify以及notifyAll方法
Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notif ...
- 多线程中的"断点"续传《notify()和wait()》
眼下在做一个项目.关于软件管理与下载的,预计项目提交日期定在6月9号.项目做了有20天了,可是在一个功能上卡住了.在这个项目中有一个功能----APK的下载须要实现. 相信大家都玩过非常多关于下载AP ...
- python多线程中join()的理解
在 Python 的多线程编程中,经常碰到 thread.join()这样的代码.那么今天咱们用实际代码来解释一下 join 函数的作用. 第一,当一个进程启动之后,会默认产生一个主线程,因为线程是程 ...
- Java多线程中线程间的通信
一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.u ...
- wait和notify的理解与使用
1.对于wait()和notify()的理解 对于wait()和notify()的理解,还是要从jdk官方文档中开始,在Object类方法中有: void notify() Wakes up a si ...
随机推荐
- dubbo forbid 注意的几种方式
1.检查所调用的项目模块是否起来了 2.如果起来后,检查该模块配置是否正确 3.服务端起来后与管理端的项目内容不一致(比如服务端增加了东西,管理端没有更新)
- swift基础语法之控件使用02
//第一个控制器:显示基础控件 import UIKit class ViewController: UIViewController { var label: UILabel = UILabel() ...
- 一个Tomcat配置参数引发的血案
转载:https://mp.weixin.qq.com/s/3IuTcDCTB3yIovp6o_vuKA 一.现象 有用户反馈访问PC首页偶尔会出现白页情况,也偶尔会收到听云的报警短信 二.监控(听云 ...
- 算法笔记_163:算法提高 最大乘积(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢? 输入格式 第一行一个数表示数据组数 每组输入数据共2行: 第1行给出总共的数 ...
- push和unshift方法
push和unushift都是向数组插入元素. push是向数组尾部插入元素. unshift是向数组头部插入元素. 共同点:都可以一次插入多个元素. arrayObject.push(newelem ...
- FIS3项目构建
概述 FIS3采取了类似CSS语法一样的配置风格,易于理解与上手.FIS3 是面向前端的工程构建工具.解决前端工程中性能优化.资源加载(异步.同步.按需.预加载.依赖管理.合并.内嵌).模块化开发.自 ...
- JAVA小项目实例源码—学习娱乐小助手
代码地址如下:http://www.demodashi.com/demo/11456.html 一.程序实现 项目目录: MyJFrame:实现项目界面样式: AppProcess:实现调用api或爬 ...
- 学会Git玩转Github笔记(一)——Github基本概念 & 仓库管理
一.github基本概念 使用目的:借助GitHub托管项目代码 1.仓库(Respository) 2.收藏(Star) 3.复制克隆项目(Fork) :分叉—你开源了一个项目,别人想在你这个项目基 ...
- hibernate3和4中 HibernateSessionFactory中不同之处 The method applySettings(Map) from the type ServiceRegistryBuilder is deprecated - The type ServiceRegistryBuilder is deprecated
hibernate3和4中 HibernateSessionFactory中不同之处 //serviceRegistry = new ServiceRegistryBuilder().applySet ...
- django inspectdb
使用inspectdb --通过已有数据库表生成 model.pyinspectdb辅助工具检查你的settings文件指向的数据库,决定你表示你的表的Django模型并打印Python模型代码到标 ...