java多线程之wait()和sleep()的区别
2018-06-27 本文已影响62人
一个菜鸟JAVA
1.方法所属不同
wait()是Object上的方法,而sleep()是属于Thread上的方法
2.锁对象释放与否
sleep()
方法导致了程序暂停执行指定的时间,让出cpu给其他线程,但是他的监控状态依然保持者,
当指定的时间到了又会自动恢复运行状态。
重点:不会释放锁对象
wait()
线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()
或者notifyAll()
方法后本线程才进入对象锁定池准备.
重点:会释放锁对象
下面给出测试代码:
package com.zc.thread;
/**
* Created by zengchao
*/
public class App {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
//sleep()
new Thread(new A(lock)).start();
Thread.sleep(1000L);
new Thread(new B(lock)).start();
//wait()
// new Thread(new C(lock)).start();
// Thread.sleep(1000L);
// new Thread(new D(lock)).start();
}
private static class A extends Thread{
private Object lock;
public A(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("线程A获取到锁,进入5秒睡眠");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程A执行完成");
}
}
}
private static class B extends Thread{
private Object lock;
public B(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("线程B获取到锁");
System.out.println("线程B完成");
}
}
}
private static class C extends Thread{
private Object lock;
public C(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("线程C获取到锁");
System.out.println("线程C调用wait,释放锁");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程C执行完成");
}
}
}
private static class D extends Thread{
private Object lock;
public D(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("线程D获取到锁");
System.out.println("线程D执行完成,调用notify()唤醒线程C");
lock.notify();
}
}
}
}
第一次执行
Object lock = new Object();
//sleep()
new Thread(new A(lock)).start();
Thread.sleep(1000L);
new Thread(new B(lock)).start();
结果:
线程A获取到锁,进入5秒睡眠
线程A执行完成
线程B获取到锁
线程B完成
当线程A获取到锁后,进入5秒睡眠,但是线程A任然没有释放锁,所以线程B只能等待锁,而无法运行.而当线程A执行完成之后,
释放了锁,所以B就可以执行了.
第二次执行
Object lock = new Object();
//wait()
new Thread(new C(lock)).start();
Thread.sleep(1000L);
new Thread(new D(lock)).start();
结果:
线程C获取到锁
线程C调用wait,释放锁
线程D获取到锁
线程D执行完成,调用notify()唤醒线程C
线程C执行完成
首先线程C获取到了锁,然后调用wait()方法,C线程释放锁,D线程获取到锁,执行完成之后,调用notify()唤醒C线程,C线程继续执行.
如果D线程不调用notify(),那么线程C则一直处于wait中,结果线程C执行完成
不会打印出结果,程序也不会终止.
总结
上述是个人整理出来的,不正确的地方还请各位指正.第一点其实无关紧要,最重要记住第二点即可.