java notify,wait,notifyAll理解和实例(一)
2017-05-21 18:34
423 查看
通常可以使用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对象锁的线程依旧被阻塞。
obj.notifyAll():与notify的区别是,该方法会唤醒所有正在等待obj对象锁的线程。(不过同一时刻,也只有一个线程可以拥有obj的对象锁)
要注意的是,wai,notify以及notifyAll方法的调用必须在相应的synchronized代码块之中。
下面来分析输出的结果:
start后进入await方法,需要等待5s,但是同时1s后开始进入唤醒,虽然执行了notify但是assign是同步方法,所以即使5s过完了,需要对象锁,但是也要等10s后释放对象锁才行。
第二个例子:
同时如果wait()方法里没有参数,也会被nofity或notifyAll唤醒;如果有时长参数即使不用nofity或notifyAll唤醒,到时间后也会得到对象锁,自己唤醒
第三个例子:
转自:
https://my.oschina.net/fengheju/blog/169695 http://www.yiibai.com/java_concurrency/concurrency_interthread_communication.html
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代码块之中。
编号 | 方法 | 描述 |
---|---|---|
1 | public void wait() | 使当前线程等到另一个线程调用notify()方法。 |
2 | public void notify() | 唤醒在此对象监视器上等待的单个线程。 |
3 | public 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 2017 out of notifyAll MThread assign Date1:Sun May 21 18:18:37 CST 2017 MThread assign Date2:Sun May 21 18:18:47 CST 2017 MThread await Date2:Sun May 21 18:18:47 CST 2017 out 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
相关文章推荐
- Java基础(高级)——多线程的理解和Synchronized实例,以及线程间通信,wait,notify等方法
- Java 多线程学习笔记 线程通讯 wait notify notifyAll的理解
- Java Object对象中的wait,notify,notifyAll通俗理解
- java 模拟公告板 wait -notify 实例
- java中线程wait() notify() 的理解
- java 多线程(wait/notify/notifyall)
- Java wait() notify()方法使用实例讲解
- Java 同步方式 (2) —— wait和notify/notifyall
- Java 多线程编程之五:一个理解 wait() 与 notify() 的例子
- Java 多线程(Thread) 同步(synchronized) 以及 wait, notify 相关 [实例介绍]
- java之join/wait/notify/notifyall
- 理解 JAVA线程同步及其中中wait()和notify()简洁例子
- [原]Java多线程编程学习笔记之九:使用wait/notify/notifyAll实现线程间通信的几点说明
- Java多线程同步之wait和notify/notifyall
- 关于java的synchronized关键字,wait(),notify() 的例子,方便大家快速理解和应用。
- Java 同步方式 (2) —— wait和notify/notifyall
- Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期
- java多线程当中wait notify notifyAll的使用
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
- Java 线程wait, notify and notifyAll 示例