java sleep()和wait()的区别?
sleep()和wait()都能阻塞当前线程。
区别1:
sleep()属于Thread类;wait()属于Object类。
区别2:
调用sleep()方法的过程中,线程不会释放对象锁。
调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
打个比较有味道的比喻:sleep和wait两个小朋友在拉屎,然后老师说你们两个不要拉屎了,wait小朋友乖乖地听话提起裤子从厕所里面出来了;sleep小朋友也很听话,也先不拉屎了,但是呢就是不从厕所出来;老师对sleep小朋友也没办法,只好不管他了,然后一扭头看到wait小朋友脸憋得通红,只得让wait小朋友继续去厕所;此时厕所已经有人了,wait小朋友只好重新排队;sleep小朋友在厕所听到老师走了也就继续他的事业了。
这里的两个小朋友就是线程,厕所就是对象锁。
看个示例程序:
public class MyTest { public static void main(String[] args) throws InterruptedException { Object o = new Object(); Thread t1 = new Thread(() -> { synchronized (o) { System.out.println("start t1"); try { o.wait(); } catch (InterruptedException e) { } System.out.println("end t1"); } }); Thread t2 = new Thread(() -> { synchronized (o) { System.out.println("start t2"); try { o.notify(); Thread.sleep(100L); System.out.println("t2 sleep 100 mills"); } catch (Exception e) { } } System.out.println("t2 sleep 200 mills"); try { Thread.sleep(200L); } catch (InterruptedException e) { } System.out.println("end t2"); }); t1.start(); Thread.sleep(10L); t2.start(); } }
执行结果如下:
start t1 start t2 t2 sleep 100 mills end t1 t2 sleep 200 mills end t2
两个线程执行过程如下:
1. 线程1先开始执行,获得对象锁o,输出一行字符后随即被wait方法阻塞,释放对象锁o;
2. 线程2开始执行,获得线程1释放的对象锁o,输出一行字符后调用对象锁o的notify方法唤醒线程1;
3. 线程2开始sleep,但此时线程2仍持有对象锁o,线程1虽已被唤醒但无法获得对象锁o只好继续阻塞;
4. 线程2 sleep结束,输出一行字符,释放对象o,随即输出一行字符,然后继续sleep;
5. 线程1得到对象锁,结束阻塞状态,继续执行直到结束;
6. 线程2 sleep结束,继续执行直到结束。
从这个过程中可以了解sleep和wait的区别与使用方法。
再看一个基于wait方法实现的简单锁:
public class MyLock { private boolean flag = false; public void lock() { synchronized (this) { while (flag) { try { wait();// 已经加锁,当前线程需要等待 } catch (InterruptedException e) { } } flag = true; } } public void unlock() { synchronized (this) { flag = false; notifyAll();// 释放锁时通知其他线程 } } }