介绍
基本的差别
- sleep是Thread类的方法,wait是Object类的方法
- sleep方法可以在任何地方使用,wait只能在synchronized方法或synchronized块中使用
最主要的本质区别
- Thread.sleep只会让出CPU,不会释放对象锁
- 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();
}
}
参考博客