Java多线程系列4 线程交互(wait和notify方法)
wait()/ notify()/ notifyAll()
任何Object对象都可以作为这三个方法的主调,但是不推荐线程对象调用这些方法。
1使用wait()、notify()和notifyAll()时需要首先对调用对象加锁【必须使用在同步代码块】
2调用wait()方法后,线程状态会从RUNNING变为WAITING,并将当线程加入到lock对象的等待队列中【会释放锁】 ,后面的代码就不执行了 。当被唤醒并被执行时,是接着上次执行到的wait()方法代码后面继续往下执行的。
3调用notify()或者notifyAll()方法后,等待在lock对象的等待队列的线程不会马上从wait()方法返回,必须要等到调用notify()或者notifyAll()方法的线程将lock锁释放,等待线程才有机会从等待队列返回。这里只是有机会,因为锁释放后,等待线程会出现竞争,只有竞争到该锁的线程才会从wait()方法返回,其他的线程只能继续等待
下面代码演示
public class WaitNotifyThread {
//条件是否满足的标志
private static boolean flag = true;
//对象的监视器锁
private static Object lock = new Object();
public static void main(String[] args){
Thread waitThread = new Thread(new WaitThread(),"WaitThread");
waitThread.start();
Thread notifyThread = new Thread(new NotifyThread(),"NotifyThread");
notifyThread.start();
}
/**
* 等待线程
*/
private static class WaitThread implements Runnable{
public void run() {
//加锁,持有对象的监视器锁
synchronized (lock){
//只有成功获取对象的监视器才能进入这里
//当条件不满足的时候,继续wait,直到某个线程执行了通知
//并且释放了lock的监视器(简单来说就是锁)才能从wait
//方法返回
while (flag){
try {
System.out.println(Thread.currentThread().getName() + " flag is true"
);
lock.wait(); //相当于睡眠 但是释放锁的
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//条件满足,继续工作
System.out.println(Thread.currentThread().getName() + " flag is false "
);
}
}
}
/**
* 通知线程
*/
private static class NotifyThread implements Runnable{
public void run() {
synchronized (lock){
//获取lock锁,然后执行通知,通知的时候不会释放lock锁
//只有当前线程退出了lock后,waitThread才有可能从wait返回
System.out.println(Thread.currentThread().getName() + " holds lock "
);
lock.notifyAll(); //唤醒wait 但是只有释放代码块以后 wait变成就绪
flag = false;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//再次加锁
synchronized (lock){
System.out.println(Thread.currentThread().getName() + " holds lock again "
);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
运行结果会有两种

或者

这个例子只是想说明 调用notify 或者notifyAll 并不会释放锁 要等到同步代码执行完成以后 才会释放 释放以后,两个线程的执行是不确定的
所以会有2个结果
Java多线程系列4 线程交互(wait和notify方法)的更多相关文章
- Java多线程系列--“JUC线程池”06之 Callable和Future
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
- Java多线程系列--“JUC线程池”02之 线程池原理(一)
概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...
- Java多线程系列--“JUC线程池”03之 线程池原理(二)
概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
- Java多线程系列--“JUC线程池”04之 线程池原理(三)
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...
- Java多线程系列--“JUC线程池”05之 线程池原理(四)
概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...
- Java多线程系列--“JUC线程池”01之 线程池架构
概要 前面分别介绍了"Java多线程基础"."JUC原子类"和"JUC锁".本章介绍JUC的最后一部分的内容——线程池.内容包括:线程池架构 ...
- java多线程系列(六)---线程池原理及其使用
线程池 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线程系列(三)之等待通知 ...
- Java多线程系列 JUC线程池04 线程池原理解析(三)
转载 http://www.cnblogs.com/skywang12345/p/3509954.html https://blog.csdn.net/qq_22929803/article/det ...
- Java多线程系列 JUC线程池02 线程池原理解析(一)
转载 http://www.cnblogs.com/skywang12345/p/3509960.html ; http://www.cnblogs.com/skywang12345/p/35099 ...
随机推荐
- inode引起的Linux无法创建新文件,磁盘空间不足
df -h,判断硬盘空间是否已经满了,占用率达100% ,就可以断定该分区满了. df -ia,占用率达100%,也会导致无法创建新文件.一般都是存在大量小文件引起的. inode包含文件的元信息,具 ...
- 1、Shiro 安全框架与Spring 整合详解
Apache Shiro 是一个安全认证框架,和 Spring Security 相比,在于他使用了比较简洁易懂的认证和授权方式.其提供的 native-session(即把用户认证后的授权信息保存在 ...
- ubuntu下安装owncloud提示没有zip模块时
wget http://pecl.php.net/get/zip-1.13.5.tgztar -zvxf zip-1.13.5.tgzcd zip-1.13.5phpize ./configure m ...
- PHP运行出现Notice : Use of undefined constant 的解决办法
这些是 PHP 的提示而非报错,PHP 本身不需要事先声明变量即可直接使用,但是对未声明变量会有提示.一般作为正式的网站会把提示关掉的,甚至连错误信息也被关掉 关闭 PHP 提示的方法 搜索php.i ...
- 浅析MySQL中concat以及group_concat的使用
说明: 本文中使用的例子均在下面的数据库表tt2下执行: 一.concat()函数 1.功能:将多个字符串连接成一个字符串. 2.语法:concat(str1, str2,...) 返回结果为连接 ...
- Lock的实现原理
1. Lock 的简介及使用 Lock是java 1.5中引入的线程同步工具,它主要用于多线程下共享资源的控制.本质上Lock仅仅是一个接口(位于源码包中的java\util\concurrent\l ...
- error: ‘kEmptyString’ is not a member of ‘google::protobuf::internal’
最近安装caffe,突然报这个错: .build_release/src/caffe/proto/caffe.pb.h: In member function ‘void caffe::ImageDa ...
- WPF程序 双击exe自动申请“以管理员方式运行”权限
实现方式: 在 xxx.exe 目录下包含其对应的清单文件(xxx.exe.manifest, 由 VS 编译时自动生成): 用记事本打开 manifest 文件,将文件中的项:<request ...
- 关于Bootstrap的入门知识
问:Bootstrap是什么? 答:开源的前端框架,就是一些事先写好的css.js等. 问:Bootstrap在哪儿下载? 答:官方(https://getbootstrap.com/),中文(htt ...
- Python程序互斥体
Python程序互斥体 有时候我们需要程序只运行一个实例,在windows平台下我们可以很简单的用mutex实现这个目的. 在开始时,程序创建了一个命名的mutex,这个mutex可以被其他进 ...