java中wait()和sleep()方法区别

456 阅读2分钟

定义

sleep()方法

sleep()方法是线程类(Thread)的静态方法,让调用的线程进入指定时间睡眠状态,使得当前线程进入阻塞状态,告诉系统至少在指定时间内不需要为线程调度器为该线程分配执行时间片,给执行机会给其他线程(实际上,调用sleep()方法时并不要求持有任何锁,即sleep()可在任何地方使用。),但是监控状态依然保持,到时后会自动恢复。

wait()方法

wait()方法是Object类里的方法,当一个线程执行wait()方法时,它就进入到一个和该对象相关的等待池中(进入等待队列,也就是阻塞的一种,叫等待阻塞),同时释放对象锁,并让出CPU资源,待指定时间结束后返还得到对象锁。

区别

  • sleep()方法是线程类Thread中的方法,而wait()是Object类的方法
  • sleep()方法可以在任何地方使用,而wait()方法必须在同步块中使用,即必须包含在对应的synchronzied语句中,使用前要先获得目标对象的一个监视器(notify()方法也需要先获得目标对象的一个监视器)
  • sleep()方法只让出了CPU执行时间片,而并不会释放同步资源锁,wait()方法则是当前线程让出同步资源锁

代码

sleep()使用

public class Visibility {
    private volatile static int number=0;
    private volatile static boolean ready;
    private static class ReaderThread implements Runnable{

        @Override
        public void run() {
            while(!ready) {
                System.out.println(System.currentTimeMillis()+":未修改");
            }
            System.out.println(System.currentTimeMillis()+":"+number);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new Thread(new ReaderThread()).start();
        Thread.sleep(1);
        number=666;
        ready=true;
    }
}

wait()使用

public class Test {
    public static Object object=new Object();
    public static class T1 implements Runnable{

        @Override
        public void run() {
            synchronized (object){
                System.out.println(System.currentTimeMillis()+":T1 start! ");
                try{
                    System.out.println(System.currentTimeMillis()+":T1 wait for object");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis()+":T1 end!");
            }
        }
    }
    public static class T2 implements Runnable{

        @Override
        public void run() {
            synchronized (object){
                System.out.println(System.currentTimeMillis()+":T2 start! notify one object");
                object.notify();
                try{
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis()+":T2 end!");
            }
        }
    }

    public static void main(String[] args) {
        Thread thread1=new Thread(new T1());
        Thread thread2=new Thread(new T2());
        thread1.start();
        thread2.start();
    }
}