java中sleep和wait函数的区别
sleep方法会让线程休眠一定时间,即让出cpu,当休眠结束时会继续运行
public class SleepTest {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("thread1 sleep");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 awake");
System.out.println("thread1 finish");
});
Thread t2 = new Thread(() -> {
System.out.println("thread2 finish");
});
t1.start();
t2.start();
}
}
输出结果如下
thread1 sleep
thread2 finish
thread1 awake
thread1 finish
但sleep不会改变锁的占用,当一个线程占用某个锁时,即使调用sleep休眠,线程也不会让出锁
public class SleepTest {
final static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("thread1 sleep");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 awake");
System.out.println("thread1 finish");
}
});
Thread t2 = new Thread(() -> {
synchronized (lock){
System.out.println("thread2 finish");
}
});
t1.start();
t2.start();
}
}
输出如下,线程占用的锁不会释放
thread1 sleep
thread1 awake
thread1 finish
thread2 finish
wait函数会让线程让出当前的锁,同时可指定线程等待的时间,等待时间结束时线程会继续尝试获取锁,注意是由锁对象来调用wait函数
public class SleepTest {
final static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("thread1 wait");
try {
//让出锁等待1秒
lock.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 ready");
System.out.println("thread1 finish");
}
});
Thread t2 = new Thread(() -> {
synchronized (lock){
System.out.println("thread2 finish");
}
});
t1.start();
t2.start();
}
}
输出如下
thread1 wait
thread2 finish
thread1 ready
thread1 finish
当不指定等待时间时,调用wait()的线程会一直等待,直到某个线程调用了notify或notifyall方法
public class SleepTest {
final static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("thread1 wait");
try {
//不指定wait时间
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 ready");
System.out.println("thread1 finish");
}
});
Thread t2 = new Thread(() -> {
synchronized (lock){
System.out.println("thread2 finish");
}
});
t1.start();
t2.start();
}
}
输出如下,thread1一直在等待中
thread1 wait
thread2 finish
同时wait方法只能在同步块中调用,因为要让线程让出锁,所以在其他位置调用也没有锁可让出,同时会抛异常
public class SleepTest {
final static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(() -> {
synchronized (lock){
System.out.println("thread2 finish");
}
});
t2.start();
//尝试在同步块外调用
lock.wait();
}
}
抛出异常如下
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at org.test.test.sleep.SleepTest.main(SleepTest.java:13)
总结一下,sleep和wait的区别如下
- sleep只会让线程让出cpu,并不会让出已占用的锁;wait会让线程让出当前的锁
- sleep函数需要指定休眠时间;wait函数可以不指定等待时间
- sleep函数可以在线程任何位置调用;wait函数只能在同步块中调用