詳解JAVA多執行緒(一)

黑風S發表於2014-08-07

一個執行緒可以有四個狀態:

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


相關文章