Java多线程系列(4)--线程等待与唤醒
来源:互联网 发布:discuz省市区数据库 编辑:程序博客网 时间:2024/05/29 13:22
一、wait()、notify()、notifyAll()等方法基本概述
在Object.java中,定义了wait()、notify()和notifyAll()等接口。wait()的作用就是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的的锁;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。
上述方法的详细信息如下:
notify() –唤醒在此对象监视器上等待的单个线程;
notifyAll() –唤醒在此对象监视器上等待的所有线程;
wait() —-让当前线程处于“等待(阻塞)状态”。直到其它线程调用此对象的notify()方法或者notifyAll()方法,当前线程被唤醒(进入就绪状态);
wait(long timeout) —-让当前线程处于“等待(阻塞)状态”。直到其它线程调用此对象的notify()方法或者notifyAll()方法,或者超过指定的时间量,当前线程被唤醒(进入就绪状态);
wait(long timeout,int nanos) —-让当前线程处于“等待(阻塞)状态”。直到其它线程调用此对象的notify()方法或者notifyAll()方法,或者超过指定的时间量,或者其它某个线程中断当前线程,当前线程被唤醒(进入就绪状态)
二、wait()、notify()、notifyAll()代码实例
由于与wait配合起来使用时,notify()和notifyAll()并无太大区别。下面仅通过wait与notify()代码来进行演示
package Test;/** * Created by LKL on 2017/2/20. */public class TestWaitAndNotify { public static void main(String[] args) throws InterruptedException { MyThread3 t1 = new MyThread3("t1"); // MyThread3 t2 = new MyThread3("t2"); synchronized(t1){ System.out.println(Thread.currentThread().getName()+" start t1"); // System.out.println(Thread.currentThread().getName()+" start t2"); t1.start(); // t2.start(); //主线程等待t1通过notify()唤醒 System.out.println(Thread.currentThread().getName()+" wait() "); t1.wait(); //此时持有t1这个对象的锁的是object System.out.println(Thread.currentThread().getName()+" continue "); } }}package Test;/** * Created by LKL on 2017/2/20. */public class MyThread3 extends Thread{ public MyThread3(String name) { super(name); } public void run(){ synchronized(this){ System.out.println(Thread.currentThread().getName()+" call notify()"); //唤醒当前线程 notify(); } }}
运行结果如下:
main start t1main wait() t1 call notify()main continue
上述流程为:
(1)主线程main通过new MyThread3(“t1”)新建线程t1,接着通过synchronized(t1)获取”获取t1对象的同步锁”,然后调用t1.start()启动线程t1。
(2)主线程main执行t1.wait()释放”t1对象的锁”,并且进入了等待(阻塞)状态。等待t1对象上的线程通过notify()或notifyAll()将其唤醒。
(3)线程t1运行之后,通过synchronized(this)获取”当前对象的锁”;接着调用notify()唤醒”当前对象上的得带线程”,此时也就意味着唤醒主线程;
(4)线程t1运行完毕之后,会释放当前对象的锁,接着,主线程获取t1对象的锁,然后接着运行。
当把上述代码修改如下时:
package Test;/** * Created by LKL on 2017/2/20. */public class TestWaitAndNotify { public static void main(String[] args) throws InterruptedException { MyThread3 t1 = new MyThread3("t1"); // MyThread3 t2 = new MyThread3("t2"); synchronized(t1){ System.out.println(Thread.currentThread().getName()+" start t1"); // System.out.println(Thread.currentThread().getName()+" start t2"); // t1.start(); // t2.start(); //主线程等待t1通过notify()唤醒 System.out.println(Thread.currentThread().getName()+" wait() "); t1.wait(); //此时持有t1这个对象的锁的是object System.out.println(Thread.currentThread().getName()+" continue "); } }}
也就是不开启t1这个线程,此时主线程main运行了t1.wait()后,一直处于阻塞状态,因为并没有线程将它唤醒。
main start t1main wait()
二、wait()、notify()总结
wait()会使当前线程等待,因为线程进入等待(阻塞)状态,所以线程应该释放它所持有的“同步锁”,否则其它线程获取不到这个“同步锁”而无法运行。
notify()和wait()直接就是依据“对象的同步锁”关联起来的。
假设我们把负责唤醒等待线程的那个线程称为唤醒线程,它只有在获取“该对象的同步锁”,此时的同步锁必须和等待线程的同步锁是同一个,并且调用notify()或调用notifyAll()方法之后,才能唤醒等待线程;但是它不能立刻执行,因为唤醒线程还持有该对象的同步锁,必须等到唤醒线程释放了对象的同步锁之后,等待线程才能获取到对象的同步锁,从而继续运行。
因此,notify()和wait()依赖于同步锁,而同步锁是对象所持有,并且每个对象只有一个。所以,wait()、notify()等方法定义在object类中,而不是Thread类中。
文章只是作为自己的学习笔记,借鉴了网上的许多案例,如果觉得阔以的话,希望多交流,在此谢过…
- Java多线程系列(4)--线程等待与唤醒
- Java多线程系列--【基础篇05】- 线程等待与唤醒
- Java多线程--线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒 (r)
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- java 线程等待与唤醒
- java 多线程—— 线程等待与唤醒
- 【Java多线程】基础线程的等待与唤醒
- Java多线程基础--05之 线程等待与唤醒
- java基本教程之java线程等待与java唤醒线程 java多线程教程
- java 多线程等待与唤醒机制
- java中线程的等待与唤醒
- java学习笔记--线程等待与唤醒
- weka中包管理器打不开问题
- linux进程管理
- Java---Dictionary 字典
- 3D打印机启动加热过慢的一个小技巧.
- 安卓开发将文件通过豌豆荚拷贝到安卓设备中失败
- Java多线程系列(4)--线程等待与唤醒
- PromiseKit入门
- maven项目 修改properties属性文件不用重启
- 关于mac下安装Brew遇到的错误记录 Warning: /usr/local/bin is not in your PATH.
- ios webview alert弹窗不显示网址解决办法
- Linux常用命令
- maven mirror 设置 settings.xml
- Java编程简单应用———1、HelloWorld(HelloWorld的来源);2、输出个人信息3、输出特殊图案
- kafka生产者和消费者的javaAPI demo