Java的多線程基於Thread,我們先看看Thread的繼承關係
public class Thread implements Runnable
可以看到Thread基礎了Runnable接口,Runnable接口僅僅有run方法,用於實現線程邏輯。
啓動線程-start方法
啓動線程需要調用start方法。備註,不要使用run方法,run方法僅僅是執行Runnable實例中的run方法,是同步的。
1)start方法使用synchronized關鍵詞修飾,保證同一時間僅執行一次
2)使用synchronized並不能保證線程多次調用,需要使用threadStatus 記錄線程狀態,僅僅爲Thread.State.NEW纔可啓動
3)使用Runnable時,主線程無法獲取子線程的異常
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
用戶線程和守護線程
守護線程,是指在程序運行的時候在後臺提供一種通用服務的線程,比如垃圾回收線程就是一個很稱職的守護者,並且這種線程並不屬於程序中不可或缺的部分。因此,當所有的非守護線程結束時,程序也就終止了,同時會殺死進程中的所有守護線程。反過來說,只要任何非守護線程還在運行,程序就不會終止。
我們在創建thread的時候默認爲用戶線程,如果要設置爲守護線程,需要調用setDaemon方法
thread.setDaemon(true); //必須在start前調用
需要注意的是:
1)在Daemon線程中產生的新線程也是Daemon的
2)守護線程應該永遠不去訪問固有資源,如文件、數據庫,因爲它會在任何時候甚至在一個操作的中間發生中斷。