面试官:同样是等待,说一下sleep和wait的区别_对象锁

介绍

基本的差别

  1. sleep是Thread类的方法,wait是Object类的方法
  2. sleep方法可以在任何地方使用,wait只能在synchronized方法或synchronized块中使用

最主要的本质区别

  1. Thread.sleep只会让出CPU,不会释放对象锁
  2. Object.wait不仅让出CPU,还会释放对象锁。只有针对此对象调用notify()方法或者时间到了,才能再次执行

示例代码1

public class WaitSleepDemo {

public static void main(String[] args) {
Object lock = new Object();

new Thread(() -> {
System.out.println("Thread A is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread A get lock");
Thread.sleep(1000);
System.out.println("Thread A is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();

// 为了先执行Thread A 再执行 Thread B
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}

new Thread(() -> {
System.out.println("Thread B is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread B get lock");
lock.wait(1000);
System.out.println("Thread B is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

}

输出为

Thread A is waiting to get lock
Thread A get lock
Thread B is waiting to get lock
Thread A is done
Thread B get lock
Thread B is done

由输出可以看到Thread.sleep不会释放锁,因为A完成了B才拿到锁

public class WaitSleepDemo {

public static void main(String[] args) {
Object lock = new Object();

new Thread(() -> {
System.out.println("Thread A is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread A get lock");
lock.wait(1000);
System.out.println("Thread A is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();

// 为了先执行Thread A 再执行 Thread B
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}

new Thread(() -> {
System.out.println("Thread B is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread B get lock");
Thread.sleep(1000);
System.out.println("Thread B is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

}

我们将sleep和wait换一下,输出为

Thread A is waiting to get lock
Thread A get lock
Thread B is waiting to get lock
Thread B get lock
Thread B is done
Thread A is done

可以看到Object.wait会释放锁,因为A还没有执行完,锁就被B获得了

去掉try catch方便看

public class WaitSleepDemo {

public static void main(String[] args) {
Object lock = new Object();

new Thread(() -> {
System.out.println("Thread A is waiting to get lock");
synchronized (lock) {
System.out.println("Thread A get lock");
Thread.sleep(1000);
System.out.println("Thread A is done");
}
}).start();

// 为了先执行Thread A 再执行 Thread B
Thread.sleep(20);

new Thread(() -> {
System.out.println("Thread B is waiting to get lock");
synchronized (lock) {
System.out.println("Thread B get lock");
lock.wait(1000);
System.out.println("Thread B is done");
}
}).start();
}

}
public class WaitSleepDemo {

public static void main(String[] args) {
Object lock = new Object();

new Thread(() -> {
System.out.println("Thread A is waiting to get lock");
synchronized (lock) {
System.out.println("Thread A get lock");
lock.wait(1000);
System.out.println("Thread A is done");
}
}).start();

// 为了先执行Thread A 再执行 Thread B
Thread.sleep(20);

new Thread(() -> {
System.out.println("Thread B is waiting to get lock");
synchronized (lock) {
System.out.println("Thread B get lock");
Thread.sleep(1000);
System.out.println("Thread B is done");
}
}).start();
}

}

面试官:同样是等待,说一下sleep和wait的区别_示例代码_02

参考博客