2016.8.5
寫這么個(gè)例子:
有一個(gè)盒子,里面只能放一個(gè)數(shù)字,
盒子空時(shí)生產(chǎn)者才能放入數(shù)字,
盒子滿時(shí)消費(fèi)者才能取出數(shù)字。
盒子
class Box {
public int boxValue=0;
}
生產(chǎn)者
class Producer extends Thread{
private Box box;
public Producer(Box box){
this.box=box;
}
public void run(){
for(int i=1;i<=10;i++){
synchronized(box){
while(box.boxValue!=0){
System.out.println("生產(chǎn)者:滿了");
try {
box.wait();//線程休眠,等待喚醒,并釋放box對(duì)象鎖
} catch (InterruptedException e) {
e.printStackTrace();
}
}
box.boxValue=i;
System.out.println("生產(chǎn)者放入了數(shù)字:"+i);
box.notify();//隨機(jī)喚醒一個(gè)正在等待box的線程
}
}
}
}
消費(fèi)者
class Consumer extends Thread{
private Box box;
public Consumer(Box box){
this.box=box;
}
public void run(){
for(int i=1;i<=5;i++){
synchronized(box){
while(box.boxValue==0){
System.out.println("消費(fèi)者:空了");
try {
box.wait();//線程休眠,等待喚醒,并釋放box對(duì)象鎖
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消費(fèi)者取出了數(shù)字:"+box.boxValue);
box.boxValue=0;
box.notify();//隨機(jī)喚醒一個(gè)正在等待box的線程
}
}
}
}
運(yùn)行
public static void main(String[] args){
Box box = new Box();
Thread producer = new Producer(box);
Thread consumer = new Consumer(box);
producer.start();
consumer.start();
}
結(jié)果

搜狗截圖20160805142606.png
總結(jié)
- wait()和notify()只能寫在synchronized同步方法或同步塊中。
- wait(),線程休眠,等待喚醒,并釋放對(duì)象鎖(monitor)
- notify(),隨機(jī)喚醒一個(gè)正在等待對(duì)象鎖的線程
- notifyAll(),喚醒所有正在等待對(duì)象鎖的線程
- 若沒有正在等待對(duì)象鎖的線程,則notify()和notifyAll()不起作用
- 一個(gè)線程被喚醒不代表立即獲取了對(duì)象的monitor,只有等調(diào)用完notify()或者notifyAll()并退出synchronized塊,釋放對(duì)象鎖后,其余線程才可獲得鎖執(zhí)行。
- 至于哪個(gè)線程接下來能夠獲取到對(duì)象的monitor就具體依賴于操作系統(tǒng)的調(diào)度了。