首先来看一个最简单的例子,
任何一个对象都有锁,wait,notify,以及notifyAll方法。
这个例子可以帮助我们理解wait的作用以及锁的概念。
public class Exampe1 {
public static String lock="1";
public static void main(String[] args) {
System.out.println("before--");
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("after--");
}
}
这是以上代码的运行结果:
before--
这里只是打印了前一句before。
代码分析:
synchronized (lock) {
}先获得对象的锁。
lock.wait()释放锁,也就是不占用cpu了。
整个程序也就不会运行了。
因为整个主线程进入了lock对象的等待池中。
下面来看下一个例子加深理解,该例子有两个类。
子线程:
主线程:
public class M {
public static String u="i";
public static void main(String[] args) {
myTestThread t= new myTestThread();
t.start();//启动子线程,请注意看子线程类。该子线程运行后会进入m对象的等待池。
synchronized(u){//让主线程进入等待1000us。
try {
u.wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
synchronized (t.m) {//唤醒子线程。该子线程为t。而t是进入m对象的等待池中的,所以必须用t的m对象唤醒它。
t.m.notify();
}
}
}
子线程类代码:
public class myTestThread extends Thread {
public String m="1";
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (m) {//是m对象害的我啊。。。
try {
System.out.println("当前时间--"+System.currentTimeMillis()+"--我就要进行等待池了啊。。。。");
m.wait();//让子线程进入自己的等待池
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("当前时间--"+System.currentTimeMillis()+"--我被唤醒了啊嘿嘿嘿嘿嘿。。。。");
System.out.println("mytest thread -- notify-- ");
}
}
运行结果:
当前时间--1394790871367--我就要进行等待池了啊。。。。
当前时间--1394790872367--我被唤醒了啊嘿嘿嘿嘿嘿。。。。
mytest thread -- notify--
注意:子线程进入等待池和被唤醒的时间正好是1000us。也就是主线程等待的时间,说明这1000us子线程一直处于等待状态,直到被主线程调用m对象的notify()方法。
notify()为唤醒一个等待池中的线程。notifyAll为唤醒等待池中所有的线程。