一、共同点
首先wait(long)方法和sleep(long)方法的效果都是让当前线程暂时放弃CPU的使用权,进入阻塞状态。其中wait()方法有一个无参的方法。
二、不同点
1.方法归属不同
- sleep(long)是Thread的静态方法
- wait()、wait(long)都是Object的成员方法,每个对象都有
2.醒来的时机不同
wait(long)和wait()还可以被notify唤醒,wait()如果不唤醒就会一直等待下去
但是都可以通过interrupt进行中断唤醒
3.锁特性不同💡
- wait方法的调用必须先获取wait对象的锁,而sleep无限制
- wait方法执行后会释放对象锁,允许其他线程获得对象锁(我放弃cpu,你们也可以用)
- sleep如果在synchronized代码块中执行,并不会释放对象锁(我放弃cpu,但你们也用不了)
测试代码:
public class TestSleepAndWait {
private static final Object object=new Object();//对象锁
public static void main(String[] args) {
Thread t1=new Thread(()->{
synchronized (object){
try {
System.out.println("t1线程争抢到锁.....");
//sleep方法
//Thread.sleep(5000); sleep方法不会释放锁 所以t1线程在sleep期间 t2线程也没有执行权 需要等待t1线程sleep结束后执行完毕才能执行
//wait方法 wait方法会释放锁 将cpu交给其他线程去执行任务
object.wait(1000);
System.out.println("t1线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1");
Thread t2=new Thread(()->{
synchronized (object){
System.out.println("t2线程争抢到锁......");
}
},"t2");
t1.start();
t2.start();
}
}
其中t1线程和t2线程共用1个object对象锁,在t1线程中当我们使用的wait()方法时,按照wait()方法的特性,当t1线程调用wait方法时,此时会释放对象锁object,让出cpu,那么t2线程就可以拿到object对象锁执行任务。
而使用的是sleep方法时,那么t1线程在等待的过程中也不会释放锁,而t2线程拿不到object对象锁,只能等待t1线程sleep结束并执行完毕才可以拿到锁执行。