當前位置:首頁 » 編程語言 » java線程應用

java線程應用

發布時間: 2025-09-11 11:58:29

A. java的線程在項目中一般會有什麼具體的應用

java線程在項目中的應用場景如下:

場景一:一個業務邏輯有很多次的循環,每次循環之間沒有影響,比如驗證1萬條url路徑是否存在,正常情況要循環1萬次,逐個去驗證每一條URL,這樣效率會很低,假設驗證一條需要1分鍾,總共就需要1萬分鍾,有點恐怖。這時可以用多線程,將1萬條URL分成50等份,開50個線程,沒個線程只需驗證200條,這樣所有的線程執行完是遠小於1萬分鍾的。
場景二:需要知道一個任務的執行進度,比如我們常看到的進度條,實現方式可以是在任務中加入一個整型屬性變數(這樣不同方法可以共享),任務執行一定程度就給變數值加1,另外開一個線程按時間間隔不斷去訪問這個變數,並反饋給用戶。
總之使用多線程就是為了充分利用cpu的資源,提高程序執行效率,當你發現一個業務邏輯執行效率特別低,耗時特別長,就可以考慮使用多線程。不過CPU執行哪個線程的時間和順序是不確定的,即使設置了線程的優先順序,因此使用多線程的風險也是比較大的,會出現很多預料不到的問題,一定要多熟悉概念,多構造不同的場景去測試才能夠掌握!

B. 在JAVA中線程到底起到什麼作用

這是javaeye上非常經典的關於線程的帖子,寫的非常通俗易懂的,適合任何讀計算機的同學.
線程同步

我們可以在計算機上運行各種計算機軟體程序。每一個運行的程序可能包括多個獨立運行的線程(Thread)。
線程(Thread)是一份獨立運行的程序,有自己專用的運行棧。線程有可能和其他線程共享一些資源,比如,內存,文件,資料庫等。
當多個線程同時讀寫同一份共享資源的時候,可能會引起沖突。這時候,我們需要引入線程「同步」機制,即各位線程之間要有個先來後到,不能一窩蜂擠上去搶作一團。
同步這個詞是從英文synchronize(使同時發生)翻譯過來的。我也不明白為什麼要用這個很容易引起誤解的詞。既然大家都這么用,咱們也就只好這么將就。
線程同步的真實意思和字面意思恰好相反。線程同步的真實意思,其實是「排隊」:幾個線程之間要排隊,一個一個對共享資源進行操作,而不是同時進行操作。

因此,關於線程同步,需要牢牢記住的第一點是:線程同步就是線程排隊。同步就是排隊。線程同步的目的就是避免線程「同步」執行。這可真是個無聊的繞口令。
關於線程同步,需要牢牢記住的第二點是 「共享」這兩個字。只有共享資源的讀寫訪問才需要同步。如果不是共享資源,那麼就根本沒有同步的必要。
關於線程同步,需要牢牢記住的第三點是,只有「變數」才需要同步訪問。如果共享的資源是固定不變的,那麼就相當於「常量」,線程同時讀取常量也不需要同步。至少一個線程修改共享資源,這樣的情況下,線程之間就需要同步。
關於線程同步,需要牢牢記住的第四點是:多個線程訪問共享資源的代碼有可能是同一份代碼,也有可能是不同的代碼;無論是否執行同一份代碼,只要這些線程的代碼訪問同一份可變的共享資源,這些線程之間就需要同步。

為了加深理解,下面舉幾個例子。
有兩個采購員,他們的工作內容是相同的,都是遵循如下的步驟:
(1)到市場上去,尋找並購買有潛力的樣品。
(2)回到公司,寫報告。
這兩個人的工作內容雖然一樣,他們都需要購買樣品,他們可能買到同樣種類的樣品,但是他們絕對不會購買到同一件樣品,他們之間沒有任何共享資源。所以,他們可以各自進行自己的工作,互不幹擾。
這兩個采購員就相當於兩個線程;兩個采購員遵循相同的工作步驟,相當於這兩個線程執行同一段代碼。

下面給這兩個采購員增加一個工作步驟。采購員需要根據公司的「布告欄」上面公布的信息,安排自己的工作計劃。
這兩個采購員有可能同時走到布告欄的前面,同時觀看布告欄上的信息。這一點問題都沒有。因為布告欄是只讀的,這兩個采購員誰都不會去修改布告欄上寫的信息。

下面增加一個角色。一個辦公室行政人員這個時候,也走到了布告欄前面,准備修改布告欄上的信息。
如果行政人員先到達布告欄,並且正在修改布告欄的內容。兩個采購員這個時候,恰好也到了。這兩個采購員就必須等待行政人員完成修改之後,才能觀看修改後的信息。
如果行政人員到達的時候,兩個采購員已經在觀看布告欄了。那麼行政人員需要等待兩個采購員把當前信息記錄下來之後,才能夠寫上新的信息。
上述這兩種情況,行政人員和采購員對布告欄的訪問就需要進行同步。因為其中一個線程(行政人員)修改了共享資源(布告欄)。而且我們可以看到,行政人員的工作流程和采購員的工作流程(執行代碼)完全不同,但是由於他們訪問了同一份可變共享資源(布告欄),所以他們之間需要同步。

同步鎖

前面講了為什麼要線程同步,下面我們就來看如何才能線程同步。
線程同步的基本實現思路還是比較容易理解的。我們可以給共享資源加一把鎖,這把鎖只有一把鑰匙。哪個線程獲取了這把鑰匙,才有權利訪問該共享資源。
生活中,我們也可能會遇到這樣的例子。一些超市的外面提供了一些自動儲物箱。每個儲物箱都有一把鎖,一把鑰匙。人們可以使用那些帶有鑰匙的儲物箱,把東西放到儲物箱裡面,把儲物箱鎖上,然後把鑰匙拿走。這樣,該儲物箱就被鎖住了,其他人不能再訪問這個儲物箱。(當然,真實的儲物箱鑰匙是可以被人拿走復制的,所以不要把貴重物品放在超市的儲物箱裡面。於是很多超市都採用了電子密碼鎖。)
線程同步鎖這個模型看起來很直觀。但是,還有一個嚴峻的問題沒有解決,這個同步鎖應該加在哪裡?
當然是加在共享資源上了。反應快的讀者一定會搶先回答。
沒錯,如果可能,我們當然盡量把同步鎖加在共享資源上。一些比較完善的共享資源,比如,文件系統,資料庫系統等,自身都提供了比較完善的同步鎖機制。我們不用另外給這些資源加鎖,這些資源自己就有鎖。
但是,大部分情況下,我們在代碼中訪問的共享資源都是比較簡單的共享對象。這些對象裡面沒有地方讓我們加鎖。
讀者可能會提出建議:為什麼不在每一個對象內部都增加一個新的區域,專門用來加鎖呢?這種設計理論上當然也是可行的。問題在於,線程同步的情況並不是很普遍。如果因為這小概率事件,在所有對象內部都開辟一塊鎖空間,將會帶來極大的空間浪費。得不償失。
於是,現代的編程語言的設計思路都是把同步鎖加在代碼段上。確切的說,是把同步鎖加在「訪問共享資源的代碼段」上。這一點一定要記住,同步鎖是加在代碼段上的。
同步鎖加在代碼段上,就很好地解決了上述的空間浪費問題。但是卻增加了模型的復雜度,也增加了我們的理解難度。
現在我們就來仔細分析「同步鎖加在代碼段上」的線程同步模型。
首先,我們已經解決了同步鎖加在哪裡的問題。我們已經確定,同步鎖不是加在共享資源上,而是加在訪問共享資源的代碼段上。
其次,我們要解決的問題是,我們應該在代碼段上加什麼樣的鎖。這個問題是重點中的重點。這是我們尤其要注意的問題:訪問同一份共享資源的不同代碼段,應該加上同一個同步鎖;如果加的是不同的同步鎖,那麼根本就起不到同步的作用,沒有任何意義。
這就是說,同步鎖本身也一定是多個線程之間的共享對象。

Java語言的synchronized關鍵字

為了加深理解,舉幾個代碼段同步的例子。
不同語言的同步鎖模型都是一樣的。只是表達方式有些不同。這里我們以當前最流行的Java語言為例。Java語言裡面用synchronized關鍵字給代碼段加鎖。整個語法形式表現為
synchronized(同步鎖) {
// 訪問共享資源,需要同步的代碼段
}

這里尤其要注意的就是,同步鎖本身一定要是共享的對象。

… f1() {

Object lock1 = new Object(); // 產生一個同步鎖

synchronized(lock1){
// 代碼段 A
// 訪問共享資源 resource1
// 需要同步
}
}

上面這段代碼沒有任何意義。因為那個同步鎖是在函數體內部產生的。每個線程調用這段代碼的時候,都會產生一個新的同步鎖。那麼多個線程之間,使用的是不同的同步鎖。根本達不到同步的目的。
同步代碼一定要寫成如下的形式,才有意義。

public static final Object lock1 = new Object();

… f1() {

synchronized(lock1){ // lock1 是公用同步鎖
// 代碼段 A
// 訪問共享資源 resource1
// 需要同步
}

你不一定要把同步鎖聲明為static或者public,但是你一定要保證相關的同步代碼之間,一定要使用同一個同步鎖。
講到這里,你一定會好奇,這個同步鎖到底是個什麼東西。為什麼隨便聲明一個Object對象,就可以作為同步鎖?
在Java裡面,同步鎖的概念就是這樣的。任何一個Object Reference都可以作為同步鎖。我們可以把Object Reference理解為對象在內存分配系統中的內存地址。因此,要保證同步代碼段之間使用的是同一個同步鎖,我們就要保證這些同步代碼段的synchronized關鍵字使用的是同一個Object Reference,同一個內存地址。這也是為什麼我在前面的代碼中聲明lock1的時候,使用了final關鍵字,這就是為了保證lock1的Object Reference在整個系統運行過程中都保持不變。
一些求知慾強的讀者可能想要繼續深入了解synchronzied(同步鎖)的實際運行機制。Java虛擬機規范中(你可以在google用「JVM Spec」等關鍵字進行搜索),有對synchronized關鍵字的詳細解釋。synchronized會編譯成 monitor enter, … monitor exit之類的指令對。Monitor就是實際上的同步鎖。每一個Object Reference在概念上都對應一個monitor。
這些實現細節問題,並不是理解同步鎖模型的關鍵。我們繼續看幾個例子,加深對同步鎖模型的理解。

public static final Object lock1 = new Object();

… f1() {

synchronized(lock1){ // lock1 是公用同步鎖
// 代碼段 A
// 訪問共享資源 resource1
// 需要同步
}
}

… f2() {

synchronized(lock1){ // lock1 是公用同步鎖
// 代碼段 B
// 訪問共享資源 resource1
// 需要同步
}
}

上述的代碼中,代碼段A和代碼段B就是同步的。因為它們使用的是同一個同步鎖lock1。
如果有10個線程同時執行代碼段A,同時還有20個線程同時執行代碼段B,那麼這30個線程之間都是要進行同步的。
這30個線程都要競爭一個同步鎖lock1。同一時刻,只有一個線程能夠獲得lock1的所有權,只有一個線程可以執行代碼段A或者代碼段B。其他競爭失敗的線程只能暫停運行,進入到該同步鎖的就緒(Ready)隊列。
每一個同步鎖下面都掛了幾個線程隊列,包括就緒(Ready)隊列,待召(Waiting)隊列等。比如,lock1對應的就緒隊列就可以叫做lock1 - ready queue。每個隊列裡面都可能有多個暫停運行的線程。
注意,競爭同步鎖失敗的線程進入的是該同步鎖的就緒(Ready)隊列,而不是後面要講述的待召隊列(Waiting Queue,也可以翻譯為等待隊列)。就緒隊列裡面的線程總是時刻准備著競爭同步鎖,時刻准備著運行。而待召隊列裡面的線程則只能一直等待,直到等到某個信號的通知之後,才能夠轉移到就緒隊列中,准備運行。
成功獲取同步鎖的線程,執行完同步代碼段之後,會釋放同步鎖。該同步鎖的就緒隊列中的其他線程就繼續下一輪同步鎖的競爭。成功者就可以繼續運行,失敗者還是要乖乖地待在就緒隊列中。
因此,線程同步是非常耗費資源的一種操作。我們要盡量控制線程同步的代碼段范圍。同步的代碼段范圍越小越好。我們用一個名詞「同步粒度」來表示同步代碼段的范圍。
同步粒度
在Java語言裡面,我們可以直接把synchronized關鍵字直接加在函數的定義上。
比如。
… synchronized … f1() {
// f1 代碼段
}

這段代碼就等價於
… f1() {
synchronized(this){ // 同步鎖就是對象本身
// f1 代碼段
}
}

同樣的原則適用於靜態(static)函數
比如。
… static synchronized … f1() {
// f1 代碼段
}

這段代碼就等價於
…static … f1() {
synchronized(Class.forName(…)){ // 同步鎖是類定義本身
// f1 代碼段
}
}

但是,我們要盡量避免這種直接把synchronized加在函數定義上的偷懶做法。因為我們要控制同步粒度。同步的代碼段越小越好。synchronized控制的范圍越小越好。
我們不僅要在縮小同步代碼段的長度上下功夫,我們同時還要注意細分同步鎖。
比如,下面的代碼

public static final Object lock1 = new Object();

… f1() {

synchronized(lock1){ // lock1 是公用同步鎖
// 代碼段 A
// 訪問共享資源 resource1
// 需要同步
}
}

… f2() {

synchronized(lock1){ // lock1 是公用同步鎖
// 代碼段 B
// 訪問共享資源 resource1
// 需要同步
}
}

… f3() {

synchronized(lock1){ // lock1 是公用同步鎖
// 代碼段 C
// 訪問共享資源 resource2
// 需要同步
}
}

… f4() {

synchronized(lock1){ // lock1 是公用同步鎖
// 代碼段 D
// 訪問共享資源 resource2
// 需要同步
}
}

上述的4段同步代碼,使用同一個同步鎖lock1。所有調用4段代碼中任何一段代碼的線程,都需要競爭同一個同步鎖lock1。
我們仔細分析一下,發現這是沒有必要的。
因為f1()的代碼段A和f2()的代碼段B訪問的共享資源是resource1,f3()的代碼段C和f4()的代碼段D訪問的共享資源是resource2,它們沒有必要都競爭同一個同步鎖lock1。我們可以增加一個同步鎖lock2。f3()和f4()的代碼可以修改為:
public static final Object lock2 = new Object();

… f3() {

synchronized(lock2){ // lock2 是公用同步鎖
// 代碼段 C
// 訪問共享資源 resource2
// 需要同步
}
}

… f4() {

synchronized(lock2){ // lock2 是公用同步鎖
// 代碼段 D
// 訪問共享資源 resource2
// 需要同步
}
}

這樣,f1()和f2()就會競爭lock1,而f3()和f4()就會競爭lock2。這樣,分開來分別競爭兩個鎖,就可以大大較少同步鎖競爭的概率,從而減少系統的開銷。

信號量

同步鎖模型只是最簡單的同步模型。同一時刻,只有一個線程能夠運行同步代碼。
有的時候,我們希望處理更加復雜的同步模型,比如生產者/消費者模型、讀寫同步模型等。這種情況下,同步鎖模型就不夠用了。我們需要一個新的模型。這就是我們要講述的信號量模型。
信號量模型的工作方式如下:線程在運行的過程中,可以主動停下來,等待某個信號量的通知;這時候,該線程就進入到該信號量的待召(Waiting)隊列當中;等到通知之後,再繼續運行。
很多語言裡面,同步鎖都由專門的對象表示,對象名通常叫Monitor。
同樣,在很多語言中,信號量通常也有專門的對象名來表示,比如,Mutex,Semphore。
信號量模型要比同步鎖模型復雜許多。一些系統中,信號量甚至可以跨進程進行同步。另外一些信號量甚至還有計數功能,能夠控制同時運行的線程數。
我們沒有必要考慮那麼復雜的模型。所有那些復雜的模型,都是最基本的模型衍生出來的。只要掌握了最基本的信號量模型——「等待/通知」模型,復雜模型也就迎刃而解了。
我們還是以Java語言為例。Java語言裡面的同步鎖和信號量概念都非常模糊,沒有專門的對象名詞來表示同步鎖和信號量,只有兩個同步鎖相關的關鍵字——volatile和synchronized。
這種模糊雖然導致概念不清,但同時也避免了Monitor、Mutex、Semphore等名詞帶來的種種誤解。我們不必執著於名詞之爭,可以專注於理解實際的運行原理。
在Java語言裡面,任何一個Object Reference都可以作為同步鎖。同樣的道理,任何一個Object Reference也可以作為信號量。
Object對象的wait()方法就是等待通知,Object對象的notify()方法就是發出通知。
具體調用方法為
(1)等待某個信號量的通知
public static final Object signal = new Object();

… f1() {
synchronized(singal) { // 首先我們要獲取這個信號量。這個信號量同時也是一個同步鎖

// 只有成功獲取了signal這個信號量兼同步鎖之後,我們才可能進入這段代碼
signal.wait(); // 這里要放棄信號量。本線程要進入signal信號量的待召(Waiting)隊列

// 可憐。辛辛苦苦爭取到手的信號量,就這么被放棄了

// 等到通知之後,從待召(Waiting)隊列轉到就緒(Ready)隊列裡面
// 轉到了就緒隊列中,離CPU核心近了一步,就有機會繼續執行下面的代碼了。
// 仍然需要把signal同步鎖競爭到手,才能夠真正繼續執行下面的代碼。命苦啊。

}
}

需要注意的是,上述代碼中的signal.wait()的意思。signal.wait()很容易導致誤解。signal.wait()的意思並不是說,signal開始wait,而是說,運行這段代碼的當前線程開始wait這個signal對象,即進入signal對象的待召(Waiting)隊列。

(2)發出某個信號量的通知
… f2() {
synchronized(singal) { // 首先,我們同樣要獲取這個信號量。同時也是一個同步鎖。

// 只有成功獲取了signal這個信號量兼同步鎖之後,我們才可能進入這段代碼
signal.notify(); // 這里,我們通知signal的待召隊列中的某個線程。

// 如果某個線程等到了這個通知,那個線程就會轉到就緒隊列中
// 但是本線程仍然繼續擁有signal這個同步鎖,本線程仍然繼續執行
// 嘿嘿,雖然本線程好心通知其他線程,
// 但是,本線程可沒有那麼高風亮節,放棄到手的同步鎖
// 本線程繼續執行下面的代碼

}
}

需要注意的是,signal.notify()的意思。signal.notify()並不是通知signal這個對象本身。而是通知正在等待signal信號量的其他線程。

以上就是Object的wait()和notify()的基本用法。
實際上,wait()還可以定義等待時間,當線程在某信號量的待召隊列中,等到足夠長的時間,就會等無可等,無需再等,自己就從待召隊列轉移到就緒隊列中了。
另外,還有一個notifyAll()方法,表示通知待召隊列裡面的所有線程。
這些細節問題,並不對大局產生影響。

綠色線程

綠色線程(Green Thread)是一個相對於操作系統線程(Native Thread)的概念。
操作系統線程(Native Thread)的意思就是,程序裡面的線程會真正映射到操作系統的線程,線程的運行和調度都是由操作系統控制的
綠色線程(Green Thread)的意思是,程序裡面的線程不會真正映射到操作系統的線程,而是由語言運行平台自身來調度。
當前版本的Python語言的線程就可以映射到操作系統線程。當前版本的Ruby語言的線程就屬於綠色線程,無法映射到操作系統的線程,因此Ruby語言的線程的運行速度比較慢。
難道說,綠色線程要比操作系統線程要慢嗎?當然不是這樣。事實上,情況可能正好相反。Ruby是一個特殊的例子。線程調度器並不是很成熟。
目前,線程的流行實現模型就是綠色線程。比如,stackless Python,就引入了更加輕量的綠色線程概念。在線程並發編程方面,無論是運行速度還是並發負載上,都優於Python。
另一個更著名的例子就是ErLang(愛立信公司開發的一種開源語言)。
ErLang的綠色線程概念非常徹底。ErLang的線程不叫Thread,而是叫做Process。這很容易和進程混淆起來。這里要注意區分一下。
ErLang Process之間根本就不需要同步。因為ErLang語言的所有變數都是final的,不允許變數的值發生任何變化。因此根本就不需要同步。
final變數的另一個好處就是,對象之間不可能出現交叉引用,不可能構成一種環狀的關聯,對象之間的關聯都是單向的,樹狀的。因此,內存垃圾回收的演算法效率也非常高。這就讓ErLang能夠達到Soft Real Time(軟實時)的效果。這對於一門支持內存垃圾回收的語言來說,可不是一件容易的事情。

C. 鑳借В閲婁竴涓媕ava鐨勭嚎紼嬬殑浣跨敤

闅忕潃璁$畻鏈虹殑椋為熷彂灞曪紝涓浜鴻$畻鏈轟笂鐨勬搷浣滅郴緇熶篃綰風悍閲囩敤澶氫換鍔″拰鍒嗘椂璁捐★紝灝嗘棭鏈熷彧鏈夊ぇ鍨嬭$畻鏈烘墠鍏鋒湁鐨勭郴緇熺壒鎬у甫鍒頒簡涓浜鴻$畻鏈虹郴緇熶腑銆備竴鑸鍙浠ュ湪鍚屼竴鏃墮棿鍐呮墽琛屽氫釜紼嬪簭鐨勬搷浣滅郴緇熼兘鏈夎繘紼嬬殑姒傚康銆備竴涓榪涚▼灝辨槸涓涓鎵ц屼腑鐨勭▼搴忥紝鑰屾瘡涓涓榪涚▼閮芥湁鑷宸辯嫭絝嬬殑涓鍧楀唴瀛樼┖闂淬佷竴緇勭郴緇熻祫婧愩傚湪榪涚▼姒傚康涓錛屾瘡涓涓榪涚▼鐨勫唴閮ㄦ暟鎹鍜岀姸鎬侀兘鏄瀹屽叏鐙絝嬬殑銆侸ava紼嬪簭閫氳繃嫻佹帶鍒舵潵鎵ц岀▼搴忔祦錛岀▼搴忎腑鍗曚釜欏哄簭鐨勬祦鎺у埗縐頒負綰跨▼錛屽氱嚎紼嬪垯鎸囩殑鏄鍦ㄥ崟涓紼嬪簭涓鍙浠ュ悓鏃惰繍琛屽氫釜涓嶅悓鐨勭嚎紼嬶紝鎵ц屼笉鍚岀殑浠誨姟銆傚氱嚎紼嬫剰鍛崇潃涓涓紼嬪簭鐨勫氳岃鍙ュ彲浠ョ湅涓婂幓鍑犱箮鍦ㄥ悓涓鏃墮棿鍐呭悓鏃惰繍琛屻

綰跨▼涓庤繘紼嬬浉浼礆紝鏄涓孌靛畬鎴愭煇涓鐗瑰畾鍔熻兘鐨勪唬鐮侊紝鏄紼嬪簭涓鍗曚釜欏哄簭鐨勬祦鎺у埗錛涗絾涓庤繘紼嬩笉鍚岀殑鏄錛屽悓綾葷殑澶氫釜綰跨▼鏄鍏變韓涓鍧楀唴瀛樼┖闂村拰涓緇勭郴緇熻祫婧愶紝鑰岀嚎紼嬫湰韜鐨勬暟鎹閫氬父鍙鏈夊井澶勭悊鍣ㄧ殑瀵勫瓨鍣ㄦ暟鎹錛屼互鍙婁竴涓渚涚▼搴忔墽琛屾椂浣跨敤鐨勫爢鏍堛傛墍浠ョ郴緇熷湪浜х敓涓涓綰跨▼錛屾垨鑰呭湪鍚勪釜綰跨▼涔嬮棿鍒囨崲鏃訛紝璐熸媴瑕佹瘮榪涚▼灝忕殑澶氾紝姝e洜濡傛わ紝綰跨▼琚縐頒負杞昏礋鑽瘋繘紼嬶紙light-weight process錛夈備竴涓榪涚▼涓鍙浠ュ寘鍚澶氫釜綰跨▼銆

涓涓綰跨▼鏄涓涓紼嬪簭鍐呴儴鐨勯『搴忔帶鍒舵祦銆
1. 榪涚▼錛氭瘡涓榪涚▼閮芥湁鐙絝嬬殑浠g爜鍜屾暟鎹絀洪棿錛堣繘紼嬩笂涓嬫枃錛 錛岃繘紼嬪垏鎹㈢殑寮閿澶с
2. 綰跨▼錛氳交閲忕殑榪涚▼錛屽悓涓綾葷嚎紼嬪叡浜浠g爜鍜屾暟鎹絀洪棿錛屾瘡涓綰跨▼鏈夌嫭絝嬬殑榪愯屾爤鍜岀▼搴忚℃暟鍣錛圥C錛夛紝綰跨▼鍒囨崲鐨勫紑閿灝忋
3. 澶氳繘紼嬶細鍦ㄦ搷浣滅郴緇熶腑錛岃兘鍚屾椂榪愯屽氫釜浠誨姟紼嬪簭銆
4. 澶氱嚎紼嬶細鍦ㄥ悓涓搴旂敤紼嬪簭涓錛屾湁澶氫釜欏哄簭嫻佸悓鏃舵墽琛屻

6錛1錛1 綰跨▼鐨勬傚康妯″瀷

Java鍐呭湪鏀鎸佸氱嚎紼嬶紝瀹冪殑鎵鏈夌被閮芥槸鍦ㄥ氱嚎紼嬩笅瀹氫箟鐨勶紝Java鍒╃敤澶氱嚎紼嬩嬌鏁翠釜緋葷粺鎴愪負寮傛ョ郴緇熴侸ava涓鐨勭嚎紼嬬敱涓夐儴鍒嗙粍鎴愶紝濡傚浘6.1鎵紺恆

1. 鉶氭嫙鐨凜PU錛屽皝瑁呭湪Java.lang.Thread綾諱腑銆
2. CPU鎵鎵ц岀殑浠g爜錛屼紶閫掔粰Thread綾匯
3. CPU鎵澶勭悊鐨勬暟鎹錛屼紶閫掔粰Thread綾匯

鍥6.1綰跨▼

6. 1. 2 綰跨▼浣(1)

Java鐨勭嚎紼嬫槸閫氳繃Java.lang.Thread綾繪潵瀹炵幇鐨勩傚綋鎴戜滑鐢熸垚涓涓猅hread綾葷殑瀵硅薄涔嬪悗,涓涓鏂扮殑綰跨▼灝變駭鐢熶簡銆

姝ょ嚎紼嬪疄渚嬭〃紺篔ava瑙i噴鍣ㄤ腑鐨勭湡姝g殑綰跨▼錛岄氳繃瀹冨彲浠ュ惎鍔ㄧ嚎紼嬨佺粓姝㈢嚎紼嬨佺嚎紼嬫寕璧風瓑錛屾瘡涓綰跨▼閮芥槸閫氳繃綾籘hread鍦↗ava鐨勮蔣浠跺寘Java.lang涓瀹氫箟錛屽畠鐨勬瀯閫犳柟娉曚負錛

public Thread 錛圱hreadGroup group錛孯unnable target錛孲tring name錛夛紱

鍏朵腑錛実roup 鎸囨槑璇ョ嚎紼嬫墍灞炵殑綰跨▼緇勶紱target瀹為檯鎵ц岀嚎紼嬩綋鐨勭洰鏍囧硅薄錛屽畠蹇呴』瀹炵幇鎺ュ彛Runnable錛 name涓虹嚎紼嬪悕銆侸ava涓鐨勬瘡涓綰跨▼閮芥湁鑷宸辯殑鍚嶇О錛孞ava鎻愪緵浜嗕笉鍚孴hread綾繪瀯閫犲櫒錛屽厑璁哥粰綰跨▼鎸囧畾鍚嶇О銆傚傛灉name涓簄ull鏃訛紝鍒橨ava鑷鍔ㄦ彁渚涘敮涓鐨勫悕縐般
褰撲笂榪版瀯閫犳柟娉曠殑鏌愪釜鍙傛暟涓簄ull鏃訛紝鎴戜滑鍙寰楀埌涓嬮潰鐨勫嚑涓鏋勯犳柟娉曪細

public Thread 錛堬級錛
public Thread 錛圧unnable target錛夛紱
public Thread 錛圧unnable target錛孲tring name錛夛紱
public Thread 錛圫tring name錛夛紱
public Thread 錛圱hreadGroup group錛孯unnable target錛夛紱
public Thread 錛圱hreadGroup group錛孲tring name錛夛紱

涓涓綾誨0鏄庡疄鐜癛unnable鎺ュ彛灝卞彲浠ュ厖褰撶嚎紼嬩綋錛屽湪鎺ュ彛Runnable涓鍙瀹氫箟浜嗕竴涓鏂規硶 run錛堬級錛
public void run錛堬級錛

浠諱綍瀹炵幇鎺ュ彛Runnable鐨勫硅薄閮藉彲浠ヤ綔涓轟竴涓綰跨▼鐨勭洰鏍囧硅薄錛岀被Thread鏈韜涔熷疄鐜頒簡鎺ュ彛Runnable錛屽洜姝ゆ垜浠鍙浠ラ氳繃涓ょ嶆柟娉曞疄鐜扮嚎紼嬩綋銆

錛堜竴錛夊畾涔変竴涓綰跨▼綾伙紝瀹冪戶鎵跨嚎紼嬬被Thread騫墮噸鍐欏叾涓鐨勬柟娉 run錛堬級錛岃繖鏃跺湪鍒濆嬪寲榪欎釜綾葷殑瀹炰緥鏃訛紝鐩鏍噒arget鍙涓簄ull錛岃〃紺虹敱榪欎釜瀹炰緥瀵規潵鎵ц岀嚎紼嬩綋銆傜敱浜嶫ava鍙鏀鎸佸崟閲嶇戶鎵匡紝鐢ㄨ繖縐嶆柟娉曞畾涔夌殑綾諱笉鑳藉啀緇ф壙鍏跺畠鐖剁被銆

錛堜簩錛夋彁渚涗竴涓瀹炵幇鎺ュ彛Runnable鐨勭被浣滀負涓涓綰跨▼鐨勭洰鏍囧硅薄錛屽湪鍒濆嬪寲涓涓猅hread綾繪垨鑰匱hread瀛愮被鐨勭嚎紼嬪硅薄鏃訛紝鎶婄洰鏍囧硅薄浼犻掔粰榪欎釜綰跨▼瀹炰緥錛岀敱璇ョ洰鏍囧硅薄鎻愪緵綰跨▼浣 run錛堬級銆傝繖鏃訛紝瀹炵幇鎺ュ彛Runnable鐨勭被浠嶇劧鍙浠ョ戶鎵垮叾瀹冪埗綾匯

姣忎釜綰跨▼閮芥槸閫氳繃鏌愪釜鐗瑰畾Thread瀵硅薄鐨勬柟娉時un( )鏉ュ畬鎴愬叾鎿嶄綔鐨勶紝鏂規硶run( )縐頒負綰跨▼浣撱傚浘6.2琛ㄧず浜咼ava綰跨▼鐨勪笉鍚岀姸鎬佷互鍙婄姸鎬佷箣闂磋漿鎹㈡墍璋冪敤鐨勬柟娉曘

鍥6.2 綰跨▼鐨勭姸鎬

1. 鍒涘緩鐘舵(new Thread)
鎵ц屼笅鍒楄鍙ユ椂錛岀嚎紼嬪氨澶勪簬鍒涘緩鐘舵侊細
Thread myThread = new MyThreadClass( );
褰撲竴涓綰跨▼澶勪簬鍒涘緩鐘舵佹椂錛屽畠浠呬粎鏄涓涓絀虹殑綰跨▼瀵硅薄錛岀郴緇熶笉涓哄畠鍒嗛厤璧勬簮銆

2. 鍙榪愯岀姸鎬( Runnable )
Thread myThread = new MyThreadClass( );
myThread.start( );
褰撲竴涓綰跨▼澶勪簬鍙榪愯岀姸鎬佹椂錛岀郴緇熶負榪欎釜綰跨▼鍒嗛厤浜嗗畠闇鐨勭郴緇熻祫婧愶紝瀹夋帓鍏惰繍琛屽苟璋冪敤綰跨▼榪愯屾柟娉曪紝榪欐牱灝變嬌寰楄ョ嚎紼嬪勪簬鍙榪愯( Runnable )鐘舵併傞渶瑕佹敞鎰忕殑鏄榪欎竴鐘舵佸苟涓嶆槸榪愯屼腑鐘舵侊紙Running )錛屽洜涓虹嚎紼嬩篃璁稿疄闄呬笂騫舵湭鐪熸h繍琛屻傜敱浜庡緢澶氳$畻鏈洪兘鏄鍗曞勭悊鍣ㄧ殑錛屾墍浠ヨ佸湪鍚屼竴鏃跺埢榪愯屾墍鏈夌殑澶勪簬鍙榪愯岀姸鎬佺殑綰跨▼鏄涓嶅彲鑳界殑錛孞ava鐨勮繍琛岀郴緇熷繀欏誨疄鐜拌皟搴︽潵淇濊瘉榪欎簺綰跨▼鍏變韓澶勭悊鍣ㄣ

3. 涓嶅彲榪愯岀姸鎬侊紙Not Runnable錛
榪涘叆涓嶅彲榪愯岀姸鎬佺殑鍘熷洜鏈夊備笅鍑犳潯錛
1) 璋冪敤浜唖leep錛堬級鏂規硶;
2) 璋冪敤浜唖uspend錛堬級鏂規硶;
3) 涓虹瓑鍊欎竴涓鏉′歡鍙橀噺錛岀嚎紼嬭皟鐢╳ait錛堬級鏂規硶;
4) 杈撳叆杈撳嚭嫻佷腑鍙戠敓綰跨▼闃誨;
涓嶅彲榪愯岀姸鎬佷篃縐頒負闃誨炵姸鎬侊紙Blocked錛夈傚洜涓烘煇縐嶅師鍥狅紙杈撳叆/杈撳嚭銆佺瓑寰呮秷鎮鎴栧叾瀹冮樆濉炴儏鍐碉級錛岀郴緇熶笉鑳芥墽琛岀嚎紼嬬殑鐘舵併傝繖鏃跺嵆浣垮勭悊鍣ㄧ┖闂詫紝涔熶笉鑳芥墽琛岃ョ嚎紼嬨

4. 姝諱骸鐘舵侊紙Dead錛
綰跨▼鐨勭粓姝涓鑸鍙閫氳繃涓ょ嶆柟娉曞疄鐜幫細鑷鐒舵挙娑堬紙綰跨▼鎵ц屽畬錛夋垨鏄琚鍋滄錛堣皟鐢╯top()鏂規硶錛夈傜洰鍓嶄笉鎺ㄨ崘閫氳繃璋冪敤stop()鏉ョ粓姝㈢嚎紼嬬殑鎵ц岋紝鑰屾槸璁╃嚎紼嬫墽琛屽畬銆

http://www.bc-cn.net/Article/kfyy/java/jc/200410/83.html

熱點內容
猴子桃子編程 發布:2025-09-11 14:11:10 瀏覽:993
學電腦編程多少錢 發布:2025-09-11 14:06:35 瀏覽:804
什麼叫初始支付密碼 發布:2025-09-11 13:55:13 瀏覽:78
絕對優化演算法 發布:2025-09-11 13:54:23 瀏覽:945
怎麼讀腳本 發布:2025-09-11 13:53:32 瀏覽:726
phpsession過期時間 發布:2025-09-11 13:45:54 瀏覽:658
大話西遊跑商腳本 發布:2025-09-11 13:43:33 瀏覽:1002
浪潮大存儲 發布:2025-09-11 13:43:29 瀏覽:81
雲虛擬主機是伺服器嗎 發布:2025-09-11 13:27:05 瀏覽:139
androidhttphttps 發布:2025-09-11 13:13:02 瀏覽:25