先声明一下水印问题,一开始公众号是叫午茶电影,后面我又改了个名字,但是在写这篇文章的时候,还是原来那个名字,这绝对不是转载的,因为你搜wuchastory公众号,就能搜到我这个。
线程大家都有在使用,但是有时候也仅仅是使用,对它的一些行为还不是特别的了解,今天就来和大家谈谈线程的状态这个内容。
首先线程有哪些状态呢?
这个问题,我们可以从Java的源代码中找到的答案,先简单粗暴,直接贴上代码,看看线程的状态有哪些:
看完了,大家也知道了,线程有6个状态。
这6个状态分别是:New, Runnable, Blocked, Waiting, Timed_Waiting, Terminated.
分别是什么意思呢?咱们一一来解释,其实说起来也简单。
New:这个状态呢,就是线程对象创建之后、启动之前,就是这个状态。
用代码来说呢,就是
这个New状态很好理解。
Runnable: 当调用start方法后呢,线程就会进入Runnable状态,表示,我这个线程可以被执行了,如果调度器给这个线程分配了CPU时间,那么这个线程就可以被执行,这里一定要正确区分一下Runnable不是说正在执行,而是可以被执行,这两个还是有区别的。
Blocked: 这个状态,当线程要进入临界区的时候,会发生。比如说,前面有一个临界区的代码需要执行,那么线程就会进入这个状态,如果只有一个线程呢,那么也就只有它一个在进入临界区了,它就会进入临界区开始执行,随后转为Runnable状态。如果有多个线程到了临界区,那么都会进入Blocked状态,由调度器选一个来执行,如果这个线程执行完毕后,大家还是一同为Blocked状态,调度器再选一个来执行。
所以很有可能发生的情况是,选了A线程执行,BCD都在等着,A执行完了后,还是偏心的选了A线程执行。
Waiting: waiting状态,当你调用了wait,join方法后,就会进入这个状态。一旦进入到这个状态,CPU就不会管你了,直到有别的线程通过notify方法将它唤起,否则的话,就会一直在等待中。设计这个状态怎么用呢?我的理解是,线程A需要完成一些事情,但是这些事情必须要满足某些条件才能继续,因此,如果我写一个死循环在这里等待,就很优雅了(浪费CPU资源),这时就可以使用这个waiting状态,条件未满足前,我进入waiting状态,等条件满足了,别人来通知我,我在继续执行。
Timed_Waiting: 这个状态也是等待,但是是有一个计时器在里面,最常见的是使用Thread.sleep方法触发,触发后,线程就进入了Timed_waiting状态,随后会由计时器触发,再进入Runnable状态。
Terminated: 终结状态,当线程的所有代码都被执行完毕后,会进入到这个状态,这个就是字面意思了。
总的来说,状态切换如下图所示了:
可见,几个重要状态的切换都是从Runnable转换出去,再转换回来的
然而……
咱们还是得实践一把,才能整明白啊,光纸上谈兵咋行呢。于是我就凭空捏造了一个需求:
有一个4*50的二维数组,用4个线程去分5个阶段去填满它,也就说,第一阶段大家一起填0-9,当大家都填满了0-9,再一起去填10-19,以此类推,先填满的线程要等着其他线程都填好了,再继续。
这样就能看到4个线程争先恐后的填数组,跑得快的还得先等着跑得慢的,然后大家再继续跑第二阶段。
这里直接放上效果图(下面是GIF,会动的):
代码放在github上了,如需自取:https://github.com/krossford/...
如果大家喜欢我的文章,请关注我新开的公众号:好奇码农君
微信公众号:好奇码农君
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。