它们的区别主要考虑两点:1.cpu是否继续执行、2.锁是否释放掉。
对于这两点,首先解释下cpu是否继续执行的含义:cpu为每个线程划分时间片去执行,每个时间片时间都很短,cpu不停地切换不同的线程,以看似他们好像同时执行的效果。
其次解释下锁是否释放的含义:锁如果被占用,那么这个执行代码片段是同步执行的,如果锁释放掉,就允许其它的线程继续执行此代码块了。
明白了以上两点的含义,开始分析sleep和wait:
sleep一段时间之后,往往线程会立即执行,可见cpu一直在为此线程分配时间片,如果外层包有Synchronize,那么此锁并没有释放掉。因此sleep cpu继续执行、锁并没有释放掉;
wait,一般用于锁机制中,肯定是要释放掉锁的,因为notify并不会立即调起此线程,因此cpu是不会为其分配时间片的,也就是说wait 线程进入等待池,cpu不分时间片给它,锁释放掉。
以上只是理论上,下面用代码进行尝试:
/** * Created by lizhiqiang on 2016/12/23. */ public class testSleep { public static void main(String[] args){ new Thread(new Runnable() { @Override public void run() { synchronized (this){ try { Thread.sleep(100000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } }
/** * Created by lizhiqiang on 2016/12/23. */ public class testWait { public static void main(String[] args){ new Thread(new Runnable() { @Override public void run() { synchronized (this){ try { this.wait(100000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } }执行结果:
testSleep有一个线程进入睡眠态,testWait有一个线程进入等待态。
cpu均进入0%(均有偶尔1%的情况)。
IO操作:sleep的IO操作比wait的IO操作要少,应该是wait的时候将上下文进行保存导致。