一、wait()方法
- wait方法是Object的方法,是每一个类都拥有的一个方法
- wait()方法一般和notify()/notifyAll()、synchronized(Object){..}一起用.同时Object.wait()必须在synchronized(Object object){}代码块中使用
- 当调用wait方法的时候会释放对象锁,
- 当调用notify()方法时只是会唤醒一个线程从等待队列转换到lock blocked pool中,等一个线程执行完毕以后,JVM会让线程获得对象锁
二、sleep()方法
- sleep()是Thread类的静态方法,当调用此方法时,拥有的是一个Thread类锁,那么为什么在一个线程中调用此方法会阻止其他线程的运行??
- 网上说sleep()不会释放对象锁,这个对象指的是谁??其实这个对象指的就是synchronized关键字锁住的那个对象
- 下面的例子中说在主线程中调用sleep()方法以后,其他线程就都会休眠,而在自己的线程中调用sleep()方法说不会释放对象锁,在Thread2获得的是SleepAndWait的对象锁,调用sleep()并不会释放synchronized锁住的那个锁就是SleepAndWait对象锁。
- 但是在主线程中调用sleep方法的时候,那么主线程获得是哪个对象的锁,sleep()方法是一个静态方法,获得的肯定是一个类锁,而不是一个对象锁???
package java_lang_Object;
/**
* Created by luckyboy on 2018/7/4.
*/
public class SleepAndWait {
public static void main(String[] args){
new Thread(new Thread1()).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Thread2()).start();
}
}
class Thread1 implements Runnable{
@Override
public void run() {
synchronized (SleepAndWait.class){
System.out.println("thread1 has entered..."+System.currentTimeMillis());
System.out.println("thread1 is waiting..."+System.currentTimeMillis());
try{
SleepAndWait.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 is going on....."+System.currentTimeMillis());
System.out.println("thread1 is over....."+System.currentTimeMillis());
}
}
}
class Thread2 implements Runnable{
@Override
public void run() {
synchronized (SleepAndWait.class){
System.out.println("thread2 has entered..."+System.currentTimeMillis());
System.out.println("thread2 is sleeping..."+System.currentTimeMillis());
SleepAndWait.class.notify();
try{
Thread.sleep(5000);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("thread2 is going on....."+System.currentTimeMillis());
System.out.println("thread2 is over....."+System.currentTimeMillis());
}
}
}
输出结果
thread1 has entered...1532700544787
thread1 is waiting...1532700544787
thread2 has entered...1532700549788
thread2 is sleeping...1532700549788
thread2 is going on.....1532700554789
thread2 is over.....1532700554789
thread1 is going on.....1532700554789
thread1 is over.....1532700554790
结果分析:
我们可以看到,当线程Thread1开始执行以后,进入到同步代码块中,然后调用了从Object中继承的方法wait(),这个时候,Thread1就进入了等待队列中,如果锁住的这个对象没有在别处调用notify()方法,那么Thread1就会无线等待下去。
一旦Thread1调用wait(),此时主线程就开始执行Thread.sleep()方法将会睡眠5s钟。一旦睡眠结束,Thread2被创建,同时获得SleepAndWait对象锁。并使用SleepAndWait.class.notify()方法唤醒在等待状态的Thread1。此时我们需要注意的是,我们的Thread2并没有马上放弃SleepAndWait对象锁。而是睡眠了5s钟以后执行完程序以后退出run()方法,释放synchronized对象锁。这个时候Thread1重新获得对象锁执行结束。
参考文章
https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html