线程的状态 参见
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 )
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();
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();
}
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");
}
}
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
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
lala();
System.out.println("lala end");
}
System.out.println("lala end");
}
static class Call {
public synchronized void callFinish() {
notify();
}
}
}
public synchronized void callFinish() {
notify();
}
}
}
结果是:
en
lala
lala end
notify end
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);
Thread thread = new Thread() {
public void run() {
try {
Thread.sleep(1000);
synchronized(call){
call.notify();
}
call.notify();
}
Thread.sleep(1000);
System.out.println("notify end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread.start();
}
System.out.println("notify end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread.start();
}
notify()让因wait()进入阻塞队列里的线程(blocked状态)变为runnable,然后发出notify()动作的线程继续执行完,待其完成后,进行调度时,调用wait()的线程可能会被再次调度而进入running状态。