wait和notify、notifyall
wait方法导致当前线程等待, 加入该对象的等待集合中, 并且放弃当前持有的对象锁。
notify/notifyAll方法唤醒一个或所有正在等待这个对象锁的线程。
注意:
- 虽然会wait自动解锁, 但是对顺序有要求, 如果在notify被调用之后, 才开始wait方法
的调用, 线程会永远处于WAITING状态
- 这些方法只能由同一对象锁的持有者线程调用, 也就是写在同步块里面, 否则会抛出
IllegalMonitorStateException异常。
- wait()和notify()方法必须在synchronized标识的方法内使用。
- wait()方法调用后,会破坏原子性,线程被中断后,wait后面的方法将不在执行。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| class Q { int n; boolean valueSet = false; synchronized int get() { while(!valueSet) { try { wait(); } catch(InterruptedException e) { System.out.println("InterruptedExeption caught"); } } System.out.println("Got :" + n); valueSet = false; notify(); return n; } synchronized void put(int n) { while(valueSet) { try { wait(); } catch(InterruptedException e) { System.out.println("InterruptedExeption caught"); } } this.n = n; valueSet = true; System.out.println("Put :" + n); notify(); } }
class Producer implements Runnable { Q q; Producer(Q q) { this.q =q; new Thread(this, "Producer").start(); } public void run() { int i = 0; while(true) { q.put(i++); } } }
class Consumer implements Runnable { Q q; Consumer(Q q) { this.q = q; new Thread(this, "Consumer").start(); } public void run() { while(true) { q.get(); } } }
public class LearnThreadComm { public static void main(String args[]) { Q q = new Q(); new Producer(q); new Consumer(q); System.out.println("Stop"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class LearnWait1 { public static Object iceCream = null;
public static void main(String[] args) { LearnWait1 wai = new LearnWait1(); try { wai.DeadLock(); } catch (Exception e) { e.printStackTrace(); } }
public void DeadLock() throws Exception { new Thread(() -> { if (iceCream == null) { try { Thread.sleep(5000L); System.out.println("没有冰激凌, 小朋友不开心, 等待..."); synchronized (this){ this.wait(); } } catch (InterruptedException e1) { e1.printStackTrace(); } } System.out.println("小朋友买到冰激凌, 开心回家"); }).start(); Thread.sleep(3000L); iceCream = new Object(); synchronized (this){ this.notifyAll(); } System.out.println("通知小朋友"); } }
|