任何一個時刻,對象的控制權(monitor)只能被一個線程擁有。java
不管是執行對象的wait、notify仍是notifyAll方法,必須保證當前運行的線程取得了該對象的控制權(monitor)多線程
若是在沒有控制權的線程裏執行對象的以上三種方法,就會報java.lang.IllegalMonitorStateException異常。ide
JVM基於多線程,默認狀況下不能保證運行時線程的時序性性能
IllegalMonitorStateException wait 仍是notify 都必須確保本身取得對象的鎖 this
若是不使用wait¬ify的話,線程就會一直嘗試去佔用鎖,會浪費性能。spa
wait 會釋放鎖 可是notify會釋放嗎? 若是不會釋放 會發生什麼事情 。
線程
不會釋放 若是釋放了線程運行到一半會有問題 一直要到整個同步語句自行完成以後纔會釋放。code
package org.famous.unyielding.current; import java.util.Vector; public class Client { public static void main(String[] args) { int goods = 0; Object pLock = new Object(); Vector<String> message = new Vector<String>(); Thread customer = new Thread(new Customer(message, "customer", pLock)); Thread producter = new Thread(new Producter(message, "producter", pLock)); customer.start(); producter.start(); } } package org.famous.unyielding.current; import java.util.Vector; /** * * @author patzheng * */ public class Customer implements Runnable { private Vector<String> messages = new Vector(); private String threadName; private Object pLock; public Customer(Vector<String> messages, String threadName, Object pLock) { this.messages = messages; this.threadName = threadName; this.pLock = pLock; } @Override public void run() { Thread.currentThread().setName(threadName); System.err.println(Thread.currentThread().getName() + "Goods's size" + messages.size()); synchronized (pLock) { while (true) { if (messages.size() <= 0) { try { pLock.wait(); System.err.println("customer wait"); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.err.println(Thread.currentThread().getName() + "Goods's size" + messages.size()); System.err.println("customer notify producer"); messages.remove(0); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } pLock.notify(); } } } } } package org.famous.unyielding.current; import java.util.Date; import java.util.Vector; public class Producter implements Runnable { private Vector<String> messages = new Vector(); private String threadName; private Object pLock; public Producter(Vector<String> messages, String threadName, Object pLock) { this.messages = messages; this.threadName = threadName; this.pLock = pLock; } @Override public void run() { Thread.currentThread().setName(threadName); System.err.println(Thread.currentThread().getName() + "Goods's size" + messages.size()); synchronized (pLock) { while (true) { if (messages.size() >= 1) { try { System.err.println("producer wait"); pLock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { messages.add(new Date().toString()); System.err.println(Thread.currentThread().getName() + "Goods's size" + messages.size()); System.err.println("producer notify customer"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } pLock.notify(); } } } } }