关于sleep()方法和wait()方法的区别
最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁)。
wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
是不是看了也不理解,直接上代码
sleep方法没有释放锁,而wait方法释放了锁代码示例:
public class SleepVsWaitDemo {
public static void main(String[] args) {
new Thread(() -> {
synchronized (SleepVsWaitDemo.class) {
try {
//System.out.println(Thread.currentThread().getName() + " start sleep ...");
//Thread.sleep(3000);
System.out.println("A SleepVsWaitDemo.class start wait ...");
SleepVsWaitDemo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " stop ...");
}
}, "A").start();
//让线程A先启动
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
//SleepVsWaitDemo.class.notify();//java.lang.IllegalMonitorStateException (SleepVsWaitDemo.java:36)
synchronized (SleepVsWaitDemo.class) {
SleepVsWaitDemo.class.notify();
System.out.println(Thread.currentThread().getName() + " start sleep ...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " stopped ...");
}
}, "B").start();
}
}
结果如下:
A SleepVsWaitDemo.class start wait ...//SleepVsWaitDemo.class wait后让出锁定的资源,所以B线程执行
B start sleep ...
B stopped ...
A stop ...
如果8、9行打开,10、11行注释掉,即调用sleep方法,那么不会让出加锁的资源,也就是这里的A线程先执行完后才轮到B线程执行:
A start sleep ...//A sleep后仍然持有锁。所以B不会先于A执行
A stop ...//A 线程先执行完后 B才执行
B start sleep ...
B stopped ...
wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
上代码:27行注释取消,39行注释开启,即notify方法不在同步块里面,直接报异常
new Thread(() -> {
SleepVsWaitDemo.class.notify();//java.lang.IllegalMonitorStateException (SleepVsWaitDemo.java:36)
synchronized (SleepVsWaitDemo.class) {
//SleepVsWaitDemo.class.notify();
System.out.println(Thread.currentThread().getName() + " start sleep ...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " stopped ...");
}
}, "B").start();