notify和wait
??????? synchronized(b){...};的意思是定义一个同步块,使用b作为资源锁。b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机会执行,在这里要用同一把锁的就是b线程本身.这个线程在执行到一定地方后用notify()或者notifyAll()通知wait的线程,将所有wait这个锁的,锁已经用完,待notify()所在的同步块运行完之后,wait所在的线程就可以继续执行.
?
Nick says:
??? 如果不把b.wait()和b.notify()放到一个同一个锁内,会出现如下异常:
??? 如果有好几个进程在b对象阻塞,当调用一次notify时,只能有一个线程唤醒,如果使用
?
java.lang.IllegalMonitorStateException: current thread not owner
?at java.lang.Object.notify(Native Method)
?at org.apache.hadoop.ipc.ThreadB.run(WaitNotifyTest.java:100)
?
例子1:
--------------------------------------------
public class WaitNotifyTest {
?private static Call call = new Call();
?
?public static void notify1() {
? Thread thread = new Thread() {
?? public void run() {
??? try {
???? Thread.sleep(1000);
???? call.callFinish();
???? Thread.sleep(1000);
???? System.out.println("notify end");
??? } catch (InterruptedException e) {
???? // TODO Auto-generated catch block
???? e.printStackTrace();
??? }
?? }
? };
? thread.start();
?}
?
?public static void lala() {
? synchronized (call) {
?? System.out.println("en");
?? notify1();
?? try {
??? call.wait(50000);
?? } catch (InterruptedException e) {
??? // TODO Auto-generated catch block
??? e.printStackTrace();
?? }
?? System.out.println("lala");
? }
?}
?
?/**
? * @param args
? */
?public static void main(String[] args) {
? // TODO Auto-generated method stub
?
? lala();
? System.out.println("lala end");
?}
?
?static class Call {
? public synchronized void callFinish() {
?? notify();
? }
?}
}
?
结果是:
en
lala
lala end
notify end
?
这里表面上看似乎notify没有在一个锁里面,但是注意到callFinish()是有synchronized 修饰的,相当于synchronized(this){...} 而在lala里面有一个synchronized (call) {} 这个call对象和 call.callFinish()都是一个对象,所以他们是针对同一个对象的锁。
或者如下写:
?public static void notify1() {
? Thread thread = new Thread() {
?? public void run() {
??? try {
???? Thread.sleep(1000);
????????? synchronized(call){
????????????? call.notify();
???????? }
?
???? Thread.sleep(1000);
???? System.out.println("notify end");
??? } catch (InterruptedException e) {
???? // TODO Auto-generated catch block
???? e.printStackTrace();
??? }
?? }
? };
? thread.start();
?}
?
?
notify()让因wait()进入阻塞队列里的线程(blocked状态)变为runnable,然后发出notify()动作的线程继续执行完,待其完成后,进行调度时,调用wait()的线程可能会被再次调度而进入running状态。
?