1

先声明一下水印问题,一开始公众号是叫午茶电影,后面我又改了个名字,但是在写这篇文章的时候,还是原来那个名字,这绝对不是转载的,因为你搜wuchastory公众号,就能搜到我这个。

线程大家都有在使用,但是有时候也仅仅是使用,对它的一些行为还不是特别的了解,今天就来和大家谈谈线程的状态这个内容。

首先线程有哪些状态呢?

这个问题,我们可以从Java的源代码中找到的答案,先简单粗暴,直接贴上代码,看看线程的状态有哪些:

clipboard.png

看完了,大家也知道了,线程有6个状态。

这6个状态分别是:New, Runnable, Blocked, Waiting, Timed_Waiting, Terminated.

分别是什么意思呢?咱们一一来解释,其实说起来也简单。

New:这个状态呢,就是线程对象创建之后、启动之前,就是这个状态。

用代码来说呢,就是

clipboard.png

这个New状态很好理解。

Runnable: 当调用start方法后呢,线程就会进入Runnable状态,表示,我这个线程可以被执行了,如果调度器给这个线程分配了CPU时间,那么这个线程就可以被执行,这里一定要正确区分一下Runnable不是说正在执行,而是可以被执行,这两个还是有区别的。

clipboard.png

Blocked: 这个状态,当线程要进入临界区的时候,会发生。比如说,前面有一个临界区的代码需要执行,那么线程就会进入这个状态,如果只有一个线程呢,那么也就只有它一个在进入临界区了,它就会进入临界区开始执行,随后转为Runnable状态。如果有多个线程到了临界区,那么都会进入Blocked状态,由调度器选一个来执行,如果这个线程执行完毕后,大家还是一同为Blocked状态,调度器再选一个来执行。

所以很有可能发生的情况是,选了A线程执行,BCD都在等着,A执行完了后,还是偏心的选了A线程执行。

clipboard.png

Waiting: waiting状态,当你调用了wait,join方法后,就会进入这个状态。一旦进入到这个状态,CPU就不会管你了,直到有别的线程通过notify方法将它唤起,否则的话,就会一直在等待中。设计这个状态怎么用呢?我的理解是,线程A需要完成一些事情,但是这些事情必须要满足某些条件才能继续,因此,如果我写一个死循环在这里等待,就很优雅了(浪费CPU资源),这时就可以使用这个waiting状态,条件未满足前,我进入waiting状态,等条件满足了,别人来通知我,我在继续执行。

clipboard.png

Timed_Waiting: 这个状态也是等待,但是是有一个计时器在里面,最常见的是使用Thread.sleep方法触发,触发后,线程就进入了Timed_waiting状态,随后会由计时器触发,再进入Runnable状态。

clipboard.png

Terminated: 终结状态,当线程的所有代码都被执行完毕后,会进入到这个状态,这个就是字面意思了。

总的来说,状态切换如下图所示了:

clipboard.png

可见,几个重要状态的切换都是从Runnable转换出去,再转换回来的

然而……

clipboard.png

咱们还是得实践一把,才能整明白啊,光纸上谈兵咋行呢。于是我就凭空捏造了一个需求:

有一个4*50的二维数组,用4个线程去分5个阶段去填满它,也就说,第一阶段大家一起填0-9,当大家都填满了0-9,再一起去填10-19,以此类推,先填满的线程要等着其他线程都填好了,再继续。

这样就能看到4个线程争先恐后的填数组,跑得快的还得先等着跑得慢的,然后大家再继续跑第二阶段。

clipboard.png

这里直接放上效果图(下面是GIF,会动的):

图片描述
代码放在github上了,如需自取:https://github.com/krossford/...

如果大家喜欢我的文章,请关注我新开的公众号:好奇码农君
微信公众号:好奇码农君
关注了之后不就可以在手机上查看文章了吗!


krosshj
152 声望16 粉丝

Developer, Gamer, Artist