深入Java併發編程(一):多線程基礎

前言

本文主要講述線程實現、線程狀態、線程優先級、守護線程、線程常用API以及線程中斷和停止。

一、線程實現

1、繼承Thread類,繼承後重寫run方法,調用start()方法就可以跑起來了

2、實現Runnable接口,實現後一定要重寫run方法,然後傳參給Thread類的構造函數創建出Thread對象,然後調用start(0方法

3、實現Callable接口,與Runnable相比,執行完run方法後有返回值,其它一致

 

二、線程狀態

線程共有5種狀態:

1、創建狀態:我們創建出一個線程對象後,它就進入了創建狀態

2、運行狀態:我們調用了start()方法後,線程進入了運行狀態,此時它可能正在運行,也可能正等待CPU分配時間片

3、等待狀態:此時線程在等待其他線程的喚醒或是等待一定時間後由系統喚醒,這又可以分爲:

                         無限等待狀態:線程不會被CPU分配時間片直到其他線程的喚醒,常見用例:

                                                  未設置Timeout參數的Object.wait()

                                                  未設置Timeout參數的Thread.join()

                         限期等待狀態:線程會在一定時間後被系統自動喚醒,常見用例:

                                                   設置了Timeout參數的Object.wait()

                                                   設置了Timeout參數的Thread.join()

                                                    Thread.sleep()方法

4、阻塞狀態:此時線程正在等待獲取一個排他鎖。

5、結束狀態:線程執行完run方法後進入結束狀態

 

三、線程優先級

Java線程的優先級共有10種,默認優先級爲5,最大爲10,最小爲1。線程的優先級並不意味着一定能先得到CPU的時間片分配,只是讓其更容易被系統選擇分配。值得我們注意的是,java線程是通過映射到系統的原生線程上實現的,所以線程調度最終還是取決於操作系統,比如windows線程優先級只有7種,因此java的幾個不同優先級映射到windows中就會出現相同的情況。

四、守護線程

守護線程也被稱爲後臺線程,如要設置必須在創建狀態也就是start前設置,守護線程是可以繼承的,如果當前所有的用戶線程都退出了,那麼守護線程也會退出。守護線程的常見實例就是JVM的GC線程。

五、線程中斷

我們調用interupt()方法使得線程進入中斷狀態,這時線程內部的中斷信號會被設置爲true。我們要在線程的執行體中通過線程的中斷檢查事件(isInterrupted())判斷有無進入中斷狀態,一般而言我們會用while(Thread.currentThread().isInterrupted()){}的語法。

六、線程常用API

1、設置線程本身屬性

編號 方法 說明
1 public final void setName(String name) 設置線程名稱
2 public final void setPriority(int priority) 設置線程優先級,默認爲5
3 public final void setDaemon(boolean on) 將線程標記爲守護線程或是用戶線程

2、 其他常用方法

編號 方法 說明
1 public  void  start() 調用它使線程進入運行狀態
2 public void run() 線程運行的任務
3 public final void join();public final void join(long millisec) 主線程等待該線程運行完畢
4 public void interrupt() 設置線程中斷信號爲true
5 public final native boolean isAlive() 判斷線程是否處於運行狀態
6 public static Thread currentThread() 返回當前的對象實例
7 public static native void sleep(long millisec) 當前線程交出CPU時間片但不釋放對象鎖,一般用於線程暫停
8 public static native void yield() 暫停當前執行的線程,線程進入限期等待狀態

七、 常見問題

1、start()方法與run()方法有什麼不同?

start()方法用於啓動線程,使線程進入運行狀態,而run()方法只是實現了線程任務的一個方法,單獨運行run()方法只是讓主線程去執行了一個普通方法,並沒有創建新線程。

2、sleep()方法和wait()方法有什麼不同?

①、sleep()方法只是阻塞了線程,並未釋放鎖,wait()方法釋放了鎖;②、sleep()是Thread類下的方法,wait()方法是Object類的;3、sleep()方法一般用於暫停線程,wait()通常用於線程間的交互和通信

3、yield()和sleep()有什麼不同?

①、yield()方法執行後線程只是釋放了當前的時間片,隨時可以獲取時間片重新運行,sleep則是進入等待狀態,需要一定時間後才能重獲時間片運行;2、yield()方法只會將CPU時間片獲取機會給優先級相同或更高的線程,而sleep()方法則是一視同仁,任何線程都有機會獲取時間片;3、sleep()必須聲明InterruptedException而yield不必。

4、繼承Thread類和實現Runnable接口有什麼不同?

①我們都知道java只能單繼承,而可以實現多個接口,實現Runnable後可以繼承其他的類;②、實現Runnable接口,接口中的方法可以被其他線程共享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章