一、wait和sleep的相同点
- 都可以使线程休眠
- 都可以响应interrupt的相应
二、wait和sleep的区别
wait和sleep在参数传递上大致相同,但传递值为0时,就是天壤之别,看下面的代码:
public class Demo8 {
public static void main(String[] args) {
Thread thread1=new Thread(()->{
System.out.println("线程一开始启动");
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程一执行完成");
});
Object o=new Object();
Thread thread2=new Thread(()->{
System.out.println("线程二开始执行");
synchronized (o){
try {
o.wait(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程二执行完成");
});
thread1.start();
thread2.start();
}
}
执行结果是这样的,我们可以看出,线程二会一直等待下去,而且wait必须搭配synchronized使用
总结:
- wait必须搭配synchronized使用,sleep不用
- sleep是Thread的方法,wait是Object的方法
- sleep不释放锁,wait释放锁(见下面的代码)
- sleep有明确的终止等待时间,但是wait有可能一直等待下去
- sleep的线程状态为TIMED_WAITING,而wait是WAITING状态
public class Demo9 {
public static void main(String[] args) throws InterruptedException {
Object object1=new Object();
Object object2=new Object();
Thread thread1=new Thread(()->{
synchronized (object1) {
System.out.println("线程一开始启动");
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程一结束");
}
});
Thread thread2=new Thread(()->{
synchronized (object2){
System.out.println("线程二开始执行");
try {
object2.wait(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程二结束");
}
});
thread1.start();
thread2.start();
Thread thread3=new Thread(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object1){
System.out.println("获取到sleep的锁");
}
});
Thread thread4=new Thread(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object2){
System.out.println("获取到wait的锁");
}
});
thread3.start();
thread4.start();
}
}
这段代码的含义是:创建两个线程,并对两个对象加锁,在这两个线程中分别使用wait和sleep方法,并将等待时间大于第三个第四个线程,接下来使用线程三、四,分别访问前两个线程中上锁的对象,若能在一二线程执行期间访问到,说明当时锁已经释放。
我们可以看到,sleep的锁是等线程执行结束后才能访问,这也就说明wait释放锁,sleep不释放锁。