最近我看了混沌大学里张首晟教授的演讲,张教授始终强调一个“大道至简”的至理名言。因为所有的科学发现,技术进步都是从简单的基础知识得来的。比如:勾股定理,欧几里得几何,万有引力,相对论等,都是基于自然界的自然事实得出的。

反应到我们的编程世界。所有的思想和实践都是由最简单的基础知识构成。高并发,多线程,分布式等技术都是在基础的编程知识上得到升华的。

张教授还强调,狄拉克理论就是有狄拉克在看到数学中的开根想到的,4 开根是 2 和 -2,由此联想到了“一切粒子均有其相应的反粒子”的猜想,这一猜想后来被证实。

这就是大道至简。

在编程的世界中,不管多线程有多难,并发有多高,都离不我们的基础知识。要学习好多线程,就必须多线程的基本状态有足够的理解。本文我们一起从“图”来看看线程的基本状态吧。

了解多线程,先从“图”了解线程的基本状态!_java

  • 新建(new):新创建了一个线程对象。

  • 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取cpu的使用权。

  • 运行(running):可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。

  • 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有 机会再次获得cpu timeslice转到运行(running)状态。阻塞的情况分三种: (一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放 入等待队列(waitting queue)中。 (二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁 被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。 (三). 其他阻塞: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

  • 死亡(dead):线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

有人把线程状态的转化过程通过早起坐地铁来做了一个比喻,我觉得非常的形象。推荐给大家:从新建状态 -> 就绪状态 -> 阻塞状态 -> 运行状态 -> 死亡状态。

新建状态 New:新的一天
准备就绪 start:闹钟响了
sleeping:还没起床,请给我起床的勇气
Runnable:起床收拾好了,随时可以坐地铁出发
Waiting:等地铁来
I/O阻塞:地铁来了,但要排队上地铁
synchronized 阻塞:上了地铁,发现暂时没座位
Running:地铁上找到座位
Dead:到达目的地

世界上越是复杂的问题越有一个简单的解;越是大的道理越是简单而朴素的!所谓“大道至简”。