执行绪的四个主要周期状态如下所示:
当您实例化一个Thread对象并执行start()之后,执行绪进入Runnable状态并开始执行run()方法。
虽然执行绪看起来像是同时执行,但事实上同一时间点上,还是只有一个执行绪在动作,只是执行绪之间切换的动作很快,所以看来像是同时执行。
执行绪有其优先权,由1(Thread.MIN_PRIORITY)到10(Thread.MAX_PRIORITY),预设是 Thread.NORM_PRIORITY(5),您可以使用Thread的setPriority()方法来设定执行绪的优先权,设定必须在1到10之间,否则会丢出IllegalArgumentException。
优先权高的执行绪会先被执行完毕,然后才会轮到优先权低的执行绪,如果优先权相同,则输流执行(Round-robin方式)。
决大多数的操作系统都支持timeslicing,简单的说就是作业 系统会为每个执行绪分配一小段CPU时间(quantum),时间一到就换下一个执行绪,即使现有的执行绪还没结束。对于不支持timeslicing的 操作系统,每一个执行绪必须完成后,才能轮到下一个执行绪,在这样的操作系统中,如果您想要让目前执行绪礼让一下其它执行绪,让它们有机会取得执行权,您 可以在呼叫绪行绪的yield()方法,例如:
public class SomeClass { // ..... Thread thread = new Thread(new Runnable() { public void run() { // .... while(true) { // .... Thread.yield();?// 暂时让出执行权 } } }); thread.start(); // .... }
yield()方法让同样优先权的执行绪有被执行的机会,当执行绪执行yield()方法让出执行权时,它会再度加入执行绪的 排班,等待再度取得执行权,对于支持timeslicing的操作系统,呼叫yield()是不太需要的,因为操作系统会自动分配时间给执行绪轮流执行。
有几种状况会让执行绪进入Not Runnable状态(或是blocked状态):
当执行绪在Not Runnable状态时,执行绪是可以被执行的,但有某些原因阻止它执行(例如等待使用者的输入),执行绪排班器将不分配执行时间给这个执行绪,直到以下 的几个情况让执行绪回到Runnable状态:
当执行绪因为I/O而进入blocked状态,它必须等到I/O完成才可以离开这个状态。
最后,如果执行的工作完成(或发生例外)而离开run()方法,则执行绪执行完毕,进入Dead状态,您可以使用isAlive()方法来测试执行绪是否 存活。
如果您查询Java的在线API文件,您会发现有suspend()、resume()、stop()等方法,这些方法Java并不建议您使用,而且已经 被标示为"deprecated",这些方法建议您在需要的时候自行实作。
这边举个简单的例子,当您使用Thread.sleep()让执行绪暂停执行进入Not Runnable状态,您可以使用interrupt()让它离开Not Runnable状态,当使用sleep()暂时进入Not Runnable状态而您interrupt()时,会丢出InterruptedException例外对象,例如:
package onlyfun.caterpillar; public class InterruptDemo { public static void main(String[] args) { Thread thread1 = new Thread(new Runnable() { public void run() { try { Thread.sleep(99999); } catch(InterruptedException e) { System.out.println("I'm interrupted!!"); //e.printStackTrace(); } } }); thread1.start(); thread1.interrupt(); // interrupt it right now } }
执行结果:
I'm interrupted!
关于执行绪的wait()、notify()、notifyAll()等方法,在之后的文章中会陆续介绍。