(11)对于synchronized内部,调用了object.wait(timeout)之后且被notify()了或者超时了,如果线程无法获得锁(也就是进入了同步队列),线程处于BLOCKED状态;
(12)对于重入锁,线程执行lock.lock()的时候,如果立即获得了锁(没有进入同步队列),线程处于RUNNABLE状态;
(13)对于重入锁,线程执行lock.lock()的时候,如果无法获得锁(直接进入同步队列),线程处于WAITING状态;
(14)对于重入锁内部,调用了condition.await()之后线程处于WAITING状态(进入等待队列);
(15)对于重入锁内部,调用了condition.await(timeout)之后线程处于TIMED_WAITING状态(进入等待队列);
(16)对于重入锁内部,调用了condition.await()之后且被signal()了,如果线程立即获得了锁(也就是没有进入同步队列),线程处于RUNNABLE状态;
(17)对于重入锁内部,调用了condition.await(timeout)之后且被signal()了,如果线程立即获得了锁(也就是没有进入同步队列),线程处于RUNNABLE状态;
(18)对于重入锁内部,调用了condition.await(timeout)之后且超时了,这时如果线程正好立即获得了锁(也就是没有进入同步队列),线程处于RUNNABLE状态;
(19)对于重入锁内部,调用了condition.await()之后且被signal()了,如果线程无法获得锁(也就是进入了同步队列),线程处于WAITING状态;
(20)对于重入锁内部,调用了condition.await(timeout)之后且被signal()了或者超时了,如果线程无法获得锁(也就是进入了同步队列),线程处于WAITING状态;
(21)对于重入锁,如果内部调用了condition.await()之后且被signal()之后依然无法获取锁的,其实经历了两次WAITING状态的切换,一次是在等待队列,一次是在同步队列;
(22)对于重入锁,如果内部调用了condition.await(timeout)之后且被signal()或超时了的,状态会有一个从TIMED_WAITING切换到WAITING的过程,也就是从等待队列进入到同步队列;
为了便于理解,彤哥这里每一条都分的比较细,麻烦耐心看完。
测试用例看完上面的部分,你肯定想知道怎么去验证,下面彤哥就说说验证的方法,先给出测试用例。
public class ThreadLifeTest { public static void main(String[] args) throws IOException { Object object = new Object(); ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); new Thread(()->{ synchronized (object) { try { System.out.println("thread1 waiting"); object.wait(); // object.wait(5000); System.out.println("thread1 after waiting"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "Thread1").start(); new Thread(()->{ synchronized (object) { try { System.out.println("thread2 notify"); // 打开或关闭这段注释,观察Thread1的状态 // object.notify();【本文由公从号“彤哥读源码”原创】 // notify之后当前线程并不会释放锁,只是被notify的线程从等待队列进入同步队列 // sleep也不会释放锁 Thread.sleep(10000000); } catch (InterruptedException e) { e.printStackTrace(); } } }, "Thread2").start(); new Thread(()->{ lock.lock(); System.out.println("thread3 waiting"); try { condition.await(); // condition.await(200, (TimeUnit).SECONDS); System.out.println("thread3 after waiting"); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }, "Thread3").start(); new Thread(()->{ lock.lock(); System.out.println("thread4"); // 打开或关闭这段注释,观察Thread3的状态 // condition.signal();【本文由公从号“彤哥读源码”原创】 // signal之后当前线程并不会释放锁,只是被signal的线程从等待队列进入同步队列 // sleep也不会释放锁 try { Thread.sleep(1000000); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }, "Thread4").start(); } }打开或关闭上面注释部分的代码,使用IDEA的RUN模式运行代码,然后点击左边的一个摄像头按钮(jstack),查看各线程的状态。
注:不要使用DEBUG模式,DEBUG模式全都变成WAITING状态了,很神奇。
彩蛋其实,本来这篇是准备写线程池的生命周期的,奈何线程的生命周期写了太多,等下一篇我们再来一起学习线程池的生命周期吧。
欢迎关注我的公众号“彤哥读源码”,查看更多源码系列文章, 与彤哥一起畅游源码的海洋。