ITEEDU

Java Gossip: 执行绪生命周期

执行绪的四个主要周期状态如下所示:
執行緒生命週期

当您实例化一个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状态):

  1. 呼叫sleep()
  2. 呼叫wait()
  3. 等待I/O完成

当执行绪在Not Runnable状态时,执行绪是可以被执行的,但有某些原因阻止它执行(例如等待使用者的输入),执行绪排班器将不分配执行时间给这个执行绪,直到以下 的几个情况让执行绪回到Runnable状态:

  1. 执行绪呼叫notify()
  2. 执行绪呼叫notifyAll()
  3. 执行绪呼叫interrupt()

当执行绪因为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例外对象,例如:

InterruptDemo.java 
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()等方法,在之后的文章中会陆续介绍。