JAVA中wait和sleep的区别

1.sleep是Thread的函数,wait属于Object
2.线程中调用sleep后进入休眠状态,但并不释放锁;调用wait后会释放锁并开始等待(进入挂起状态),知道收到notify消息后再开始尝试获取锁。

Code示例:

class ThreadSleep extends Thread {
    @Override
    public void run() {
        synchronized (Main.class) {
            System.out.println("ThreadSleep Begin");
            Main.class.notify();
            try {
                System.out.println("ThreadSleep Sleep");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("ThreadSleep Awake");
            System.out.println("ThreadSleep Over");
        }
    }
}

class ThreadWait extends Thread {
    @Override
    public void run() {
        synchronized (Main.class) {
            System.out.println("ThreadWait Begin");
            try {
                System.out.println("ThreadWait Wait");
                Main.class.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("ThreadWait Continue");
            System.out.println("ThreadWait Over");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        new ThreadWait().start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        new ThreadSleep().start();
    }
}

执行结果:

ThreadWait Begin
ThreadWait Wait
ThreadSleep Begin
ThreadSleep Sleep
ThreadSleep Awake
ThreadSleep Over
ThreadWait Continue
ThreadWait Over

Main
如代码所示,Main中main函数的执行流程为:调用ThreadWait.start()->休眠->调用TheadSleep.start()
ThreadWait
ThreadWait线程在Main调用ThreadWait.start()后进入就绪状态,随后被线程调度系统转为执行状态,运行run方法中的代码。在synchronized中,获取Main.class锁,打印字符后调用wait进入挂起状态,释放Main.class锁。
ThreadSleep
ThreadSleep线程在main函数sleep(1000)后被调用,通过ThreadSleep.start()后进入就绪状态,随后被线程调度系统转为执行状态,运行run方法中的代码。在synchronized中,获取Main.class锁(由于ThreadWait在run中调用了wait,已经释放了该锁,因此ThreadSleep可以获得该锁),之后执行Main.class.notify(),唤醒挂起状态的线程(这里即为ThreadWait),通知线程可以开始尝试获取Main.class锁(这里ThreadSleep还没执行完),随后进入sleep(1000)。由于sleep不会释放锁,因此ThreadWait仍需等待,直到ThreadSleep执行完成,释放Main.class锁之后,ThreadWait才能获取到锁,继续执行剩余部分
如果在ThreadWait调用Main.class.wait()之后,程序中其他地方没执行Main.class.notify,则ThreadWait将一直wait。
程序整体执行流程图: