一个线程可以有四个状态:
1、新(new):线程对象已经创建,但尚未启动,所以不可运行
2、可运行(runnable):意味着一旦时间分片机制有空闲CPU周期提供给一个线程,那个线程便可立即开始运行,因此,线程可能在,也可能不在运行当中,但一旦条件允许,没有什么能阻止他运行,他既没有死掉,也没有被堵塞。
3、Dead:从自己的run()方法返回后,一个线程便已死掉,亦可调用stop()令其死掉,但会产生一个违例--属于error的一个子类(也就是说我们通常不捕获他),记住一个违例的掷出是一个特殊事件,而不是正常程序运行的一部分。所以不建议你用stop终止线程的运行,另外还有一个destroy()方法(他永远都不会实现),应该尽量避免调用它,因为他非常武断,根本不会接触对对象的锁定。
4、堵塞(Blocked):线程可以运行,但某种东西阻碍了他,若线程处于堵塞状态,调用机制可以简单的跳过他,不给他分配任何的CPU时间,除非线程再次进入可运行状态,否则不会采取任何操作。
线程为什么会堵塞?
堵塞状态是这四个状态中最有趣的,值得我们进一步探讨,线程被堵塞可能是由于下述五个原因造成的:
1、调用sleep(),使线程进入睡眠状态,在规定时间内这个线程是不会运行的。
2、用suspend暂停了线程的运行。除非线程收到resume()消息,否则不会返回“可运行”状态。
3、用wait()暂停了线程的执行。除非线程收到notify()或notifyall()消息,否则不会变成可执行。(这看起来和第2点非常相像,下面会做解释)
4、线程正在等待一些IO操作完成
5、线程试图调用另一个对象的同步方法,但那个对象处于锁定状态,暂时无法使用。
亦可调用yield()自动放弃CPU,以便其他线程能够运行。然而,假如调度机制觉得我们的线程已经拥有足够多的时间,并跳转到另一个线程,就会发生同样的事情。也就是说没有什么能够防止调度机制重新启动我们的线程。线程堵塞后,便有一些原因造成他不能继续执行。
下面这个例子展示了进入堵塞状态的全部五种路径。他们全都存在于名为Blocking.java的一个文件中,但在这采用散落的片段进行解释,首先让我们看看基本的框架
//: Blocking.java
// Demonstrates the various ways a thread
// can be blocked.
511
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
The basic framework ///
class Blockable extends Thread {
private Peeker peeker;
protected TextField state = new TextField(40);
protected int i;
public Blockable(Container c) {
c.add(state);
peeker = new Peeker(this, c);
}
public synchronized int read() { return i; }
protected synchronized void update() {
state.setText(getClass().getName()
+ " state: i = " + i);
}
public void stopPeeker() {
// peeker.stop(); Deprecated in Java 1.2
peeker.terminate(); // The preferred approach
}
}
class Peeker extends Thread {
private Blockable b;
private int session;
private TextField status = new TextFie ld(40);
private boolean stop = false;
public Peeker(Blockable b, Container c) {
c.add(status);
this.b = b;
start();
}
public void terminate() { stop = true; }
public void run() {
while (!stop) {
status.setText(b.getClass().getName()
+ " Peeker " + (++session)
+ "; value = " + b.read());
try {
sleep(100);
} catch (InterruptedException e){}
}
}
} ///:Continued