一. 概述
通过一个示例演示了一下,多线程技术的一个特点,它有一个并发的特点,而且具备随机性。因为cpu不断地切换造成的。
线程具备这么几种常见的状态,为什么这么说呢?刚开始我们把它创建出来,通过它的方法使它运行起来。这就发现,创建不代表运行。你必须用start给它开启了,才有资格去运行,然后它开始执行run方法中的任务,执行完了之后,线程就结束了。这样一来,线程就分为几种状态。现在,简单地把这几种状态给大家画一下。
二. 各状态的描述
1. 冻结
线程的被创建,说白了就是new一个对象,创建了一个线程的对象(本质是windows给我们创建了一个执行路径)。现在要把路径用起来,去执行我们所指定的代码,就需要对它进行处理操作。
处理就是调用start()方法,启动线程,进行运行。随着线程类内部方法run运行的执行完毕,线程就结束了。
线程的消亡有两种:一种是run()运行结束,另一种是,线程调用自己的stop()方法,(线程的消亡它自己最清楚,它是强制结束的)。
2. 冻结
(不同的书籍对于线程的划分不一样,有四种,五种,六种的....冻结状态最为重要,将其理解清楚即可)
现在不想让它消亡,想让它停一会儿。正在运行的过程中,怎么将其停止?
能够冻结起来,线程很有可能遇到了一些方法,或者功能对其进行了一些作用,而导致其冻结了。
冻结的状态特点在于,它不再运行,但是还存活。
2.1 sleep(time)
线程有一个方法,叫做sleep()方法,叫做睡眠(这一切的方法都是线程自己的,它自己能做什么,自己最清楚)。
不光可以控制睡眠,还可以控制睡眠的时间,sleep(time)。不指定time不行,必须要指定。(一直睡眠和结束有什么区别,因此要指定时间)
一睡觉就不运行了,但是还存活。如果是通过sleep()方法冻结的话,想回来特别的简单。时间一到,就回来了。
本质就是调用一些方法,方法直接拿过来用就可以了。
2.2 wait()冻结方式
还有其他的冻结方式么?
还有一种方法,可以让线程在运行的时候,变成冻结状态,就是wait()。
wait()和sleep(time)有什么区别呢?里面没有形参的存在,也就是醒不过来。没结束,又醒不过来,那有什么用?
要想让线程醒过来,必须要用另外的一种方式,wait()方法是醒不了。
用notify()方法来唤醒冻结的线程,如果线程被wait()了,我们就可以采用notify()方法将其唤醒。这就回到运行状态了。
到目前为止,线程的状态图如下所示,
三. 不同状态下线程的研究
什么时候用到冻结状态,后面会讲述到,这种状态比较特殊。这几个状态间,最重要的就是从运行到冻结。
现在要提出一些问题:如果一个线程处于运行状态,这代表着什么?这代表着cpu正在处理它,因此,运行状态的线程是具备着cpu的执行资格的,同时具备cpu的执行权。
cpu的执行资格,和cpu的执行权。执行资格代表着:可以被cpu处理,在处理队列中排队(自己组织的语言,并非专业术语)。而执行权代表着,正在被cpu处理。
线程都在运行时,有不具备资格的么?真的有。
看上图我们可以知道,运行着的程序既具备执行资格,也具备着执行权。那么冻结状态下的线程是怎样的呢?
现在总结下,不同状态下线程的特性。在运行状态时,线程具备这执行资格和执行权。在冻结状态下,执行资格和执行权,线程都不具备,完全不参与。以调用sleep()方法的线程而言,cpu是不会切换到该线程的,时间到了,线程会自动醒过来。
四. 临时阻塞状态
不同状态下,线程的情况介绍完以后,有趣的事儿就来了。
举个例子,甲乙丙丁四个线程同时向cpu发出要执行的信号,(这就意味着它们都具备着执行资格),如果cpu切换到甲上,那么甲就具备了执行权。这时,其他三个线程是什么样的呢?那种状态在目前所介绍的四种状态中没有(我可以理解为有执行资格,没有执行权么?对的)。某一时刻,只能处理一个线程。
这种特殊的状态称为临时阻塞状态。名称不重要,在这种状态下,线程是什么样的?具备执行资格,不具备执行权,等在那儿。
从冻结状态醒过来的线程,具备着执行资格,是否立马具备执行权这不一定。
要想冻结,必须先要运行,从运行才能到冻结。调用sleep()方法,必须是运行的时候才能调用,然后就变成了冻结状态。
最终的状态图如下所示:
知道了线程的不同过程,以及它们之间的转换后,才能明白线程可能遇到的一些问题。
线程最大的一个特点是随机性,不太好控制,你想去解释为什么结果是这样,你得明白线程的状态才行。
下面的三个状态作为重点来掌握。
另外一些书籍里,将线程分的更为详细,是为什么呢?将sleep(time)和wait()都给分开了,因此状态变多了。将状态涉及的运行特点搞明白,就不会乱了。