java使用wait(),notify(),notifyAll()实现等待/通知机制
public class WaitNotify {
static boolean flag=true;
static Object lock=new Object(); static class Wait implements Runnable{
@Override
public void run() {
synchronized (lock){
while(flag){
try{
System.out.println(Thread.currentThread()+" flag is true. wait " +
"@ "+new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.wait();
}catch (InterruptedException e){
}
}
}
System.out.println(Thread.currentThread()+" flag is false.running " +
"@"+new SimpleDateFormat("HH:mm:ss").format(new Date())); }
} static class Notify implements Runnable{
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread() + " hold lock. notify " +
"@ " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.notifyAll();
flag = false;
SleepUtils.second(5);
}
synchronized (lock){
System.out.println(String.format(Thread.currentThread() + " hold lock again. sleep " +
"@" + new SimpleDateFormat("HH:mm:ss").format(new Date())));
SleepUtils.second(5);
}
}
} public static void main(String[] args) {
Thread waitThread=new Thread(new Wait(),"WaitThread");
waitThread.start();
try {
TimeUnit.SECONDS.sleep(1);
}catch (InterruptedException e){ }
Thread notifyThread=new Thread(new Notify(),"NotifyThread");
notifyThread.start();
}
}
程序执行结果:
Thread[WaitThread,5,main] flag is true. wait @ 14:41:12
Thread[NotifyThread,5,main] hold lock. notify @ 14:41:13
Thread[NotifyThread,5,main] hold lock again. sleep @14:41:18
Thread[WaitThread,5,main] flag is false.running @14:41:23
1.使用wait(),notify(),notifyAll()方法之前,要获取同一个对象的锁。
2.调用wait()方法之后,线程会从RUNABLE状态变为WAITING状态,并会释放对象锁,并会将线程移入到对象的等待队列中。
3.notify()和notifyAll()调用之后,等待的线程的wait方法并不会立马返回,需要锁空闲的时候,等待的线程获取了锁,wait()方法才会返回。
4.调用了notify()和notifyAll()方法之后,notify会将一个线程从等待队列放置到同步队列,同步队列是因为锁被占有而处于BLOCKED阶段的线程,notifyAll则是将等待队列中所有的线程都移动到同步队列,这两个方法都是将线程从WAITING状态变为BLOCKED状态。
5.从wait方法返回的条件是获得了调用对象的锁。
该程序的执行流程是首先WaitThread获取了lock,然后waitThread调用wait方法,会释放锁,并将锁移入等待队列,接着notifyThread会获取锁,调用notifyAll,但是wait()方法并没有返回,因为lock没有释放,notifyThread会睡眠5秒,这时同步队列中有两个线程要获取lock,一个是notifyThread,一个是WaitThread,结果显示是notifyThread又重新获取了锁,所以这时的wait方法依然不能返回,当notifyThread执行完了之后,释放锁,waitThread获取了锁,并且wait方法返回,waitThread执行完成。
java等待/通知经典模式
等待方:
1)获取对象锁
2)如果条件不满足,那么就调用对象的wait()方法,被通知后依然要检查条件
3)条件满足则执行相应逻辑
对应的伪代码:
synchronized(对象){
while(条件不满足){
对象.wait()
}
执行对应逻辑代码
}
通知方:
1)获取对象锁
2)改变条件
3)通知所有在该对象上等待的线程
对应的伪代码:
synchronized(对象){
改变对象条件
对象.notifyAll()
}
java中的Thread.join()方法使用了等待/通知经典范式
java中的Thread.join()也算是线程通信的一种方式,表示挂起当前线程,执行子线程,等到子线程执行完成之后再返回。join()方法还提供了两个超时方法,如果子线程在规定时间没有终止,就会从join()方法中返回。
Thread.join()方法源代码:
//join函数的超时方法
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
//如果设置的超时时间小于0,抛出异常
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
//调用wait()的时候采用delay
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
} public final synchronized void join(long millis, int nanos)
throws InterruptedException { if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
} if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
} if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
} join(millis);
} public final void join() throws InterruptedException {
join(0);
}
子线程执行完成之后会调用子线程的notifyAll(),会通知所有等待在该线程对象上的方法。
java使用wait(),notify(),notifyAll()实现等待/通知机制的更多相关文章
- Java并发编程,Condition的await和signal等待通知机制
Condition简介 Object类是Java中所有类的父类, 在线程间实现通信的往往会应用到Object的几个方法: wait(),wait(long timeout),wait(long tim ...
- Java 线程间通信 —— 等待 / 通知机制
本文部分摘自<Java 并发编程的艺术> volatile 和 synchronize 关键字 每个处于运行状态的线程,如果仅仅是孤立地运行,那么它产生的作用很小,如果多个线程能够相互配合 ...
- Java Concurrency - wait & notify, 等待通知机制
生产者消费者问题是一个常见的多线程同步案例:一组生产者线程和一组消费者线程共享一个初始状态为空.大小为 N 的缓冲区.只有当缓冲区没满的时候,生产者才能把消息放入缓冲区,否则必须等待:只有缓冲区不空的 ...
- Java多线程学习(四)等待/通知(wait/notify)机制
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- java 多线程:线程通信-等待通知机制wait和notify方法;(同步代码块synchronized和while循环相互嵌套的差异);管道通信:PipedInputStream;PipedOutputStream;PipedWriter; PipedReader
1.等待通知机制: 等待通知机制的原理和厨师与服务员的关系很相似: 1,厨师做完一道菜的时间不确定,所以厨师将菜品放到"菜品传递台"上的时间不确定 2,服务员什么时候可以取到菜,必 ...
- java多线程系列(三)---等待通知机制
等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解 ...
- Java多线程之三volatile与等待通知机制示例
原子性,可见性与有序性 在多线程中,线程同步的时候一般需要考虑原子性,可见性与有序性 原子性 原子性定义:一个操作或者多个操作在执行过程中要么全部执行完成,要么全部都不执行,不存在执行一部分的情况. ...
- Java并发之等待/通知机制
目录 1 前言 1.1 先来段代码放松一下 2 Object wait()/notify() 2.1 一段入门代码 2.2 问题三连击 a.为什么官方说wait() 要放在while里面? b.为什么 ...
- 【Java并发基础】使用“等待—通知”机制优化死锁中占用且等待解决方案
前言 在前篇介绍死锁的文章中,我们破坏等待占用且等待条件时,用了一个死循环来获取两个账本对象. // 一次性申请转出账户和转入账户,直到成功 while(!actr.apply(this, targe ...
随机推荐
- SpringBoot 项目健康检查与监控(转)
前言 You build it,You run it, 当我们编写的项目上线后,为了能第一时间知晓该项目是否出现问题,常常对项目进行健康检查及一些指标进行监控.Spring Boot-Actuator ...
- CMB面试
笔试: 1.登录验证userid password后台sql传入,有什么问题,预防措施? https://bbs.csdn.net/topics/120075716 2.cookie,session, ...
- 8款不错的 CI/CD工具
Jenkins Jenkins是CI市场中最知名且最常见的名号之一.其最初是由Sun公司的一位工程师打造的一个辅助项目,并迅速扩展为最大的开源CI工具之一,可帮助工程团队实现自动化部署.顺带一提:我们 ...
- 带上RESTful的金手铐,你累吗?
1. 首先RESTful是一套规范,不是框架,它是来约束你的.也不关心生产效率的提高.就好像使用汇编开发应用,性能是快了,但是生产效率很低.RESTful它需要你在路由上定义很多规则来解释的URL,假 ...
- php curl POST multipart/form-data与application/x-www-form-urlencode的区别
背景 CURL在 a.php 中以 POST方式向 b.php 提交数据,但b.php无法接收到数据,而 CURL 操作显示成功. 原来,"传递一个数组到CURLOPT_POSTFIELDS ...
- cocos2d-x -Lua 字符串
字符串或串(String)是由数字.字母.下划线组成的一串字符. Lua 语言中字符串可以使用以下三种方式来表示: 单引号间的一串字符. 双引号间的一串字符. [[和]]间的一串字符. 以上三种方式的 ...
- centos执行-查看,复制,删除-命令的脚本
==================================================================================================== ...
- spring之文件上传
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- shell基础:数值运算与运算符
linux的shell中,变量的类型默认都是字符串型. export将aa声明为环境变量.也可用declare声明.其实就是改变了-x属性 $(()) 最常用.
- 笔记 : Ubuntu部署LNMP环境
一.准备与安装 1. 安装PHP7.1 #添加php源 :~$ sudo add-apt-repository ppa:ondrej/php #更新apt数据,载入php源数据 :~$ sudo ap ...