Bootstrap

线程基础:wait方法和sleep方法的区别

一、共同点

首先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结束并执行完毕才可以拿到锁执行。

;