java notify,wait,notifyAll理解和实例(一)
来源:互联网 发布:java调用软件api接口 编辑:程序博客网 时间:2024/05/18 15:56
通常可以使用synchronized和notify,notifyAll以及wait方法来实现线程之间的数据传递及控制。对于对象obj来说:
obj.wait():该方法的调用,使得调用该方法的执行线程(T1)放弃obj的对象锁并阻塞,直到别的线程调用了obj的notifyAll方法、或者别的线程调用了obj的notify方法且JVM选择唤醒(T1),被唤醒的线程(T1)依旧阻塞在wait方法中,与其它的线程一起争夺obj的对象锁,直到它再次获得了obj的对象锁之后,才能从wait方法中返回。(除了notify方法,wait还有带有时间参数的版本,在等待了超过所设时间之后,T1线程一样会被唤醒,进入到争夺obj对象锁的行列;另外中断可以直接跳出wait方法)
obj.notify():该方法的调用,会从所有正在等待obj对象锁的线程中,唤醒其中的一个(选择算法依赖于不同实现),被唤醒的线程此时加入到了obj对象锁的争夺之中,然而该notify方法的执行线程此时并未释放obj的对象锁,而是离开synchronized代码块时释放。因此在notify方法之后,synchronized代码块结束之前,所有其他被唤醒的,等待obj对象锁的线程依旧被阻塞。
编号 方法 描述 1
obj.wait():该方法的调用,使得调用该方法的执行线程(T1)放弃obj的对象锁并阻塞,直到别的线程调用了obj的notifyAll方法、或者别的线程调用了obj的notify方法且JVM选择唤醒(T1),被唤醒的线程(T1)依旧阻塞在wait方法中,与其它的线程一起争夺obj的对象锁,直到它再次获得了obj的对象锁之后,才能从wait方法中返回。(除了notify方法,wait还有带有时间参数的版本,在等待了超过所设时间之后,T1线程一样会被唤醒,进入到争夺obj对象锁的行列;另外中断可以直接跳出wait方法)
obj.notify():该方法的调用,会从所有正在等待obj对象锁的线程中,唤醒其中的一个(选择算法依赖于不同实现),被唤醒的线程此时加入到了obj对象锁的争夺之中,然而该notify方法的执行线程此时并未释放obj的对象锁,而是离开synchronized代码块时释放。因此在notify方法之后,synchronized代码块结束之前,所有其他被唤醒的,等待obj对象锁的线程依旧被阻塞。
obj.notifyAll():与notify的区别是,该方法会唤醒所有正在等待obj对象锁的线程。(不过同一时刻,也只有一个线程可以拥有obj的对象锁)
要注意的是,wai,notify以及notifyAll方法的调用必须在相应的synchronized代码块之中。
public void wait()
使当前线程等到另一个线程调用notify()
方法。2public void notify()
唤醒在此对象监视器上等待的单个线程。3public void notifyAll()
唤醒所有在同一个对象上调用wait()
的线程。public class Main { public static void main(String[] args) { MThread mThread = new MThread(); Thread thread = new Thread(mThread); thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } mThread.assign(); }}
import java.util.Date;/** * Created by liuyazhou on 2017/5/21. */public class MThread implements Runnable { public synchronized void assign() { System.out.println("MThread assign Date1:"+new Date()); this.notify(); System.err.println("out of notifyAll"); try { Thread.sleep(10000);//修改这个时间会发现更多 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("MThread assign Date2:"+new Date()); } public synchronized void await() throws InterruptedException { System.out.println("MThread await Date1:"+new Date()); this.wait(5000); System.err.println("out of wait"); System.out.println("MThread await Date2:"+new Date()); } @Override public void run() { try { System.out.println("MThread is running..."); await(); } catch (InterruptedException e) { } }}
MThread is running...MThread await Date1:Sun May 21 18:18:36 CST 2017out of notifyAllMThread assign Date1:Sun May 21 18:18:37 CST 2017MThread assign Date2:Sun May 21 18:18:47 CST 2017MThread await Date2:Sun May 21 18:18:47 CST 2017out of wait
下面来分析输出的结果:
start后进入await方法,需要等待5s,但是同时1s后开始进入唤醒,虽然执行了notify但是assign是同步方法,所以即使5s过完了,需要对象锁,但是也要等10s后释放对象锁才行。
第二个例子:
public class MThread implements Runnable { public synchronized void assign() { System.out.println("MThread assign Date1:"+new Date()); this.notify(); System.err.println("out of notifyAll"); try { Thread.sleep(3000);//修改这个时间会发现更多 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("MThread assign Date2:"+new Date()); } public synchronized void await() throws InterruptedException { System.out.println("MThread await Date1:"+new Date()); this.wait(5000); System.err.println("out of wait"); System.out.println("MThread await Date2:"+new Date()); } @Override public void run() { try { System.out.println("MThread is running..."); await(); } catch (InterruptedException e) { } }}//MThread is running...//MThread await Date1:Sun May 21 18:28:23 CST 2017//out of notifyAll//MThread assign Date1:Sun May 21 18:28:24 CST 2017//MThread assign Date2:Sun May 21 18:28:27 CST 2017//out of wait//MThread await Date2:Sun May 21 18:28:27 CST 2017Main.java不变,把notify所在的等待时间设为3s,加上原来的1s,总共是4s,所以即使没有到5s,也会被唤醒。
同时如果wait()方法里没有参数,也会被nofity或notifyAll唤醒;如果有时长参数即使不用nofity或notifyAll唤醒,到时间后也会得到对象锁,自己唤醒
第三个例子:
public class Main { public static void main(String[] args) { MThread mThread = new MThread(); Thread thread = new Thread(mThread); thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }// mThread.assign(); }}//MThread is running...//MThread await Date1:Sun May 21 18:39:07 CST 2017//MThread await Date2:Sun May 21 18:39:12 CST 2017//out of wait修改后的Mthread.java不变,把assign注释掉,5s后自动唤醒;如果wait不设置时长参数,会一直等待下去......
转自:
https://my.oschina.net/fengheju/blog/169695
http://www.yiibai.com/java_concurrency/concurrency_interthread_communication.html
阅读全文
0 0
- java notify,wait,notifyAll理解和实例(一)
- java wait()、notify()和notifyAll()
- JAVA多线程的理解wait、notify、notifyAll
- java wait notify notifyall
- JAVA的wait和notify和notifyall
- wait()和notify()/notifyAll()
- wait()和notify()、notifyAll()
- Java多线程3:wait、notify和notifyAll
- Java Thread wait, notify和notifyAll示例
- Java之wait()/sleep()和notify()/notifyAll()
- Java 中的 wait(), notify ()和 notifyAll ()
- Java多线程8:wait()和notify()/notifyAll()
- java多线程之wait、notify和notifyAll
- Java并发编程:wait()和notify()/notifyAll()
- Java 线程同步(wait、notify、notifyAll)
- java多线程(四)wait() notify() notifyall()
- 深入理解wait(),notify(),notifyAll()
- java线程wait、notify、notifyAll
- 栈->出栈序列判定
- python 安装dlib和boost
- 3sum和4sum(two pointers)
- oj 对称三位数素数
- 约瑟夫环
- java notify,wait,notifyAll理解和实例(一)
- lesson7.1,7.2File类和RandomAccessFile类
- node js 安装 测试
- 343. Integer Break
- java类方法继承为什么其修饰词的范围不能越来越小
- 404 page容错页面
- QT5-msvc2015 实例之计算器
- url 中提取数据
- mysql 常用sql语句