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。
程序整体执行流程图: