1. 基本的差别
sleep是Thread类的方法,wait是Object类中定义的方法
sleep方法可以在任何地方使用 ,wait方法只能在synchronized方法或synchronized块中使用
2. 最主要的本质区别
Thread.sleep只会让出CPU, 不会导致锁行为的改变
即如果当前线程拥有锁,那么Thread.sleep不会让线程释放锁,而只会主动让出CPU,CPU会可以去执行其他任务了,因此Thread.sleep不会影响锁的相关行为
Object.wait不仅让出CPU, 还会释放已经占有的同步资源锁,以便其他在等待该资源的线程得到该资源,进而去运行
3. 代码测试
public static void main(String[] args) {
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread A is waiting to get lockk");
synchronized (lock) {
try {
System.out.println("thread A get lock");
Thread.sleep(20);
System.out.println("thread A do wait method");
lock.wait(1000);
System.out.println("thread A is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread B is waiting to get lockk");
synchronized (lock) {
try {
System.out.println("thread B get lock");
System.out.println("thread B is sleeping 10ms");
Thread.sleep(20);
System.out.println("thread B is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
执行结果:
执行过程:
- System.out.println(“thread A is waiting to get lockk”);
- 执行System.out.println(“thread A get lock”);
- 执行Thread.sleep(20);
- 由于20ms大于10ms,因此线程B开始执行
- 执行 System.out.println(“thread B is waiting to get lockk”);
- 由于线程B要获取同步锁,此时我们的同步锁已经被A获取,因此线程B只能去等待,A继续执行
- 执行System.out.println(“thread A do wait method”);
- 线程A执行wait的时候,线程B开始执行,由于wait会释放锁,线程B获取到线程锁,线程B开始执行
- 执行System.out.println(“thread B get lock”);
- 执行System.out.println(“thread B is sleeping 10ms”);
- 执行Thread.sleep(20);
- 执行System.out.println(“thread B is done”);
- 执行System.out.println(“thread A is done”);
这里需要注意的是wait会释放锁。我们修改代码,查看sleep是否会释放锁
public static void main(String[] args) {
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread A is waiting to get lockk");
synchronized (lock) {
try {
System.out.println("thread A get lock");
Thread.sleep(20);
System.out.println("thread A do wait method");
Thread.sleep(1000);
System.out.println("thread A is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread B is waiting to get lockk");
synchronized (lock) {
try {
System.out.println("thread B get lock");
System.out.println("thread B is sleeping 10ms");
lock.wait(1000);
System.out.println("thread B is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
执行结果:
如执行结果显示,等A线程执行完毕释放锁之后才执行的线程B,说明sleep方法不会释放锁