Java线程的wait() 与notify()
来源:互联网 发布:淘宝祛痘产品有用吗 编辑:程序博客网 时间:2024/05/22 06:36
java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods )被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。
wait() 的方法是Object的方法,不是线程的方法,作用是让线程挂起,处于等待状态,之后可以调用notify()的方法激活线程。
也可以这样使用,线程处于运行时,判断到某个状态时调用wait(),这样线程处于等待状态,在其他地方调用object的notify的方法时,也必须获取到该线程的同步锁:
synchronized (object) {boject.notify();}
对于notify()方法,如果多个线程处于等待状态,那么被唤醒的线程由VM选择决定,调用了notify的线程将放弃对对象的锁,其他线程会尝试获得该对象的锁,获得该锁的对象将被唤醒:
notify()、wait()的方法必须要在获得锁的情况下使用,比如说在同步代码里面:
synchronized (object) {boject.notify();}
所以注意的是:
1.wait()与notify()的方法是object的共同属性,此时object当成一个同步锁。
2.wait()的方法会让线程挂起并释放锁,而notify()的方法会将挂起的线程唤醒同时在同步代码块结束后释放锁。
3.wait()与notify的方法是已经获取了锁的情况下,获取对象的monitor的方法有:
a.执行这个object的synchronized方法。
b.执行一段synchronized代码,并基于这个object的同步。
c.如果boject是class类,可以执行它的synchronized static 方法。
简单理解:wait()与notify()都是获取到同步锁的情况下才能执行的,语法上就是写在synchronized中。wait()的作用是放弃同步锁并使线程进入休眠,直到其他线程获取到同步锁使用notify()后才唤醒。Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。
使用:
1.同步锁的理解
启动十个线程线程,代码如下:
public static void main(String[] args) {Object a = new Object();for (int i = 0; i < 10; i++) {new Thread(new test2(a, i + "")).start();}}public static class test2 implements Runnable {Object lock;String name;public test2(Object lock, String name) {this.lock = lock;this.name = name;}public void run() {System.out.println(name + "开始执行");double f = 66;while (f < 30000000.0) {f = f + 0.05;}System.out.println(name + "结束执行");}}
执行结果如下:
2开始
0开始
7开始
4开始
6开始
8开始
3开始
1开始
5开始
9开始
8结束
5结束
4结束
0结束
2结束
6结束
3结束
1结束
7结束
9结束
总结:十个线程执行差不多是同时执行的,因为在循环过程中执行了耗时操作,所以所有线程执行了开始执行后才会执行结束执行操作,最先开始的不一定最先结束,因为是使用cup是随机抢占的。
加了同步锁:
public static class test2 implements Runnable {Object lock;String name;public test2(Object lock, String name) {this.lock = lock;this.name = name;}public void run() {synchronized (lock) {System.out.println(name + "开始");double f = 66;while (f < 30000000.0) {f = f + 0.05;}System.out.println(name + "结束");}}}
执行结果如下:
0开始
0结束
4开始
4结束
3开始
3结束
2开始
2结束
1开始
1结束
总结:进行同步后,其他线程会等待已经获取到同步锁的线程完成操作并将同步锁释放,释放后线程随机去抢同步锁,获取到同步锁的线程才能执行。
让线程执行了开始后就调用wait():
public static class test2 implements Runnable {Object lock;String name;public test2(Object lock, String name) {this.lock = lock;this.name = name;}public void run() {synchronized (lock) {System.out.println(name + "开始");try {//放弃锁并使当前线程休眠lock.wait();} catch (InterruptedException e) {e.printStackTrace();}double f = 66;while (f < 30000000.0) {f = f + 0.05;}System.out.println(name + "结束");}}}
打印结果如下:
0开始
2开始
1开始
3开始
4开始
总结:所有线程都调用了wait()后暂停了,由于没有唤醒所以都没有执行下面的操作。
让其中一个线程唤醒其他线程:
public static class test2 implements Runnable {Object lock;String name;public test2(Object lock, String name) {this.lock = lock;this.name = name;}public void run() {synchronized (lock) {System.out.println(name + "开始");try { //如果是第四个线程,唤醒其他的线程if (name.equals("4")) {lock.notifyAll();//lock.wait();如果加了这个后,第四个线程不会执行下面的操作} else {// 放弃锁并使当前线程休眠lock.wait();}} catch (InterruptedException e) {e.printStackTrace();}double f = 66;while (f < 30000000.0) {f = f + 0.05;}System.out.println(name + "结束");}}}
打印如下:
0开始
2开始
1开始
3开始
4开始
4结束
3结束
1结束
2结束
0结束
总结:唤醒其他线程后,那些线程将随机抢占同步锁执行下面的操作。值得注意的是,notify的方法是唤醒其他线程但是不会立即放弃同步锁,wait()是会立即放弃同步锁的。
转载注明出处:http://blog.csdn.net/u014614038/article/details/49020147
- Java线程的wait() 与notify()
- java 线程wait()与notify()的用法
- Java线程wait()与notify()
- Java线程的挂起与恢复 wait(), notify()方法介绍
- Java线程中的wait(),notify()与sleep()
- Java 线程 wait notify
- 线程通信,wait()与notify()的运用
- Java 线程的 wait()和notify()
- java线程的sleep(),wait(),notify(),yield();
- java中线程wait() notify() 的理解
- java的线程通信wait(),notify(),notifyAll()
- java,wait与notify
- java,wait与notify
- [JAVA基础] java的wait()与notify()
- java线程wait、notify、notifyAll
- java 线程同步 notify wait
- JAVA -- 线程wait()、notify()、notifyAll()
- JAVA线程 -- wait notify notifyAll
- Windows中句柄和ID的区别
- WeOnlyDo.Server服务器介绍
- javascript/JS限制用户名只能输入 汉字字母和数字下划线
- 页面Sql语句 查询根据判断值是否存在拼接查询条件
- Crontab 定时任务
- Java线程的wait() 与notify()
- linux zip 文件夹
- Window下Qt4.8.4与Mysql5.5.28 驱动生成(mingw)
- [LeetCode] Roman to Integer
- 开始写点东西
- iOS关闭键盘的两种简单方法
- 《深入理解计算机系统》读书笔记6--- 信号
- 802.11n 2乘2,3乘3
- 权限管理命令