首先,这两个都可以暂停当前线程的后续执行。但他们也有很明显的区别:
- sleep 可以用在代码中的任何地方, Thread.sleep(xxx).
- wait 是Object类型的对象的, 用在synchronized 包装的代码中。如果不在synchronized 中,会报 IllegalMonitorStateException 异常
- sleep 不会让出CPU时间片
- wait会直接让出CPU
下面通过一个例子来说明,下面是一个完整的测试代码:
1,请看下面的代码, 如果直接用lock.wait(), 会直接报 IllegalMonitorStateException
try {
System.out.println("test2");
// lock.wait(1000); IllegalMonitorStateException
System.out.println("test");
} catch (Exception e){
e.printStackTrace();
}
2,创建一个线程A, 用wait() 方法来暂停线程A:
new Thread(()->{
System.out.println("Thread A is waiting to get lock");
synchronized (lock){
System.out.println("Thead A get the lock");
try {
//object.wait 会让出时间片
lock.wait(1000);
System.out.println("Thread A done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
3,主线程暂停200毫秒:
//为了让线程A 和线程B是按照 A->B 的顺序执行的
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
4,创建一个线程B用sleep方法来暂停线程B:
new Thread(()->{
System.out.println("Thread B is waiting to get lock");
synchronized (lock){
System.out.println("Thead B get the lock");
try {
//lock.wait(1000);
//lock.notifyAll();
Thread.sleep(3000);
System.out.println("Thread B done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
该测试程序执行流程:
首先线程A启动并调用wait方法,然后会让出CPU , 200毫秒后 B线程启动,并sleep 3秒,然后B线程执行完成后归还CPU, A线程获得CPU继续执行.
打印结果如下:
test2
test
Thread A is waiting to get lock
Thead A get the lock
Thread B is waiting to get lock
Thead B get the lock
Thread B done
Thread A done
完整代码如下:
public class WaitAndSleep {
public static void main(String[] args){
Object lock = new Object();
try {
System.out.println("test2");
// lock.wait(1000); IllegalMonitorStateException
System.out.println("test");
} catch (Exception e){
e.printStackTrace();
}
new Thread(()->{
System.out.println("Thread A is waiting to get lock");
synchronized (lock){
System.out.println("Thead A get the lock");
try {
//object.wait 会让出时间片
lock.wait(1000);
System.out.println("Thread A done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
//为了让线程A 和线程B是按照 A->B 的顺序执行的
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
System.out.println("Thread B is waiting to get lock");
synchronized (lock){
System.out.println("Thead B get the lock");
try {
//lock.wait(1000);
//lock.notifyAll();
Thread.sleep(3000);
System.out.println("Thread B done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
class MyThread implements Runnable{
public void run() {
int i = 0;
while (i++ < 10){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}