sleep():可以单独使用,不释放锁
wait():必须配合synchronize、notify、notifyAll使用,释放锁
waite(int millions):释放锁,无需唤醒。时间到了,自动唤醒
public class WaitDemo implements Runnable {
private Object lock;
public WaitDemo(Object lock) {
this.lock = lock;
}
public void run() {
synchronized (lock){
System.out.println("begin wait ThreadName "+":"+Thread.currentThread().getName());
try {
//wait方法,必须在synchronize代码块中,由锁对象调用
lock.wait();
System.out.println("重新获得锁");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end wait ThreadName"+":"+Thread.currentThread().getName());
}
}
}
通知类
public class NotifyDemo implements Runnable {
private Object lock;
public NotifyDemo(Object lock) {
this.lock = lock;
}
public void run() {
synchronized (lock){
System.out.println("begin notify ThreadName"+":"+Thread.currentThread().getName());
//锁对象唤醒的是该使用该锁等待的线程
lock.notify();
try {
System.out.println("sleep 5s ...");
// sleep
Thread.sleep(5000);//sleep不释放锁
//lock.wait(5000);//释放锁。
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("end notify ThreadName"+":"+Thread.currentThread().getName());
}
System.out.println("释放锁了");
}
}
测试类
public class WaitTest {
public static void main(String[] args) {
Object obj1 = new Object();
// Object obj2 = new Object();
Runnable wait = new WaitDemo(obj1);
Runnable notify = new NotifyDemo(obj1);
Thread thread1 = new Thread(wait,"wait");
Thread thread2 = new Thread(notify,"notify");
thread1.start();
thread2.start();
}
}
- 首先执行waitDemo线程:begin wait ThreadName :wait
随之调用wait进入等待状态,并释放锁。 - 由于waitDemo进入了等待并释放了锁,所以 NotifyDemo线程获得cpu执行权,并执行,***唤醒该锁的等待线程***并输出: begin notify ThreadName:notify
sleep 5s … - 由于 NotifyDemo线程调用了sleep,所以进入等待,但是没有释放锁,所以虽然waitDemo线程被唤醒且得到了cpu但是没有锁不能够执行
- 直到 NotifyDemo sleep时间到, NotifyDemo执行:end notify ThreadName:notify
释放锁了 - waitDemo被唤醒,且获得了NotifyDemo 释放的锁,因此继续执行:重新获得锁
end wait ThreadName:wait - 总的输出结果是:
begin wait ThreadName :wait
begin notify ThreadName:notify
sleep 5s …
end notify ThreadName:notify
释放锁了
重新获得锁
end wait ThreadName:wait
**注意:**wait应该放入synchronize,并由锁对象调用。否则报错。唤醒wait的锁应该和调用wait的锁是一个对象,否则永远唤醒不了。 唤醒后,进入锁池状态继续执行,不是进入到就绪状态(因为还在synchronize中,锁也没释放)。