欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Java多線程編程總結(jié)--線程狀態(tài)的轉(zhuǎn)換

系統(tǒng) 1932 0
原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時請務(wù)必以超鏈接形式標(biāo)明文章? 原始出處 ?、作者信息和本聲明。否則將追究法律責(zé)任。 http://lavasoft.blog.51cto.com/62575/27069

一、線程狀態(tài)
?
線程的狀態(tài)轉(zhuǎn)換是線程控制的基礎(chǔ)。線程狀態(tài)總的可分為五大狀態(tài):分別是生、死、可運行、運行、等待/阻塞。用一個圖來描述如下:
、新狀態(tài):線程對象已經(jīng)創(chuàng)建,還沒有在其上調(diào)用start()方法。
?
2、可運行狀態(tài):當(dāng)線程有資格運行,但調(diào)度程序還沒有把它選定為運行線程時線程所處的狀態(tài)。當(dāng)start()方法調(diào)用時,線程首先進入可運行狀態(tài)。在線程運行之后或者從阻塞、等待或睡眠狀態(tài)回來后,也返回到可運行狀態(tài)。
?
3、運行狀態(tài):線程調(diào)度程序從可運行池中選擇一個線程作為當(dāng)前線程時線程所處的狀態(tài)。這也是線程進入運行狀態(tài)的唯一一種方式。
?
4、等待/阻塞/睡眠狀態(tài):這是線程有資格運行時它所處的狀態(tài)。實際上這個三狀態(tài)組合為一種,其共同點是:線程仍舊是活的,但是當(dāng)前沒有條件運行。換句話說,它是可運行的,但是如果某件事件出現(xiàn),他可能返回到可運行狀態(tài)。
?
5、死亡態(tài):當(dāng)線程的run()方法完成時就認(rèn)為它死去。這個線程對象也許是活的,但是,它已經(jīng)不是一個單獨執(zhí)行的線程。線程一旦死亡,就不能復(fù)生。 如果在一個死去的線程上調(diào)用start()方法,會拋出java.lang.IllegalThreadStateException異常。
?
有關(guān)詳細(xì)狀態(tài)轉(zhuǎn)換圖可以參看本人的“ Java多線程編程總結(jié) ”中的圖
?
二、阻止線程執(zhí)行
對于線程的阻止,考慮一下三個方面,不考慮IO阻塞的情況:
睡眠;
等待;
因為需要一個對象的鎖定而被阻塞。
?
1、睡眠
Thread.sleep(long millis)和Thread.sleep(long millis, int nanos)靜態(tài)方法強制當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),以“減慢線程”。當(dāng)線程睡眠時,它入睡在某個地方,在蘇醒之前不會返回到可運行狀態(tài)。當(dāng)睡眠時間到期,則返回到可運行狀態(tài)。
?
線程睡眠的原因:線程執(zhí)行太快,或者需要強制進入下一輪,因為Java規(guī)范不保證合理的輪換。
?
睡眠的實現(xiàn):調(diào)用靜態(tài)方法。
??????? try {
??????????? Thread.sleep(123);
??????? } catch (InterruptedException e) {
??????????? e.printStackTrace();?
??????? }
?
睡眠的位置:為了讓其他線程有機會執(zhí)行,可以將Thread.sleep()的調(diào)用放線程run()之內(nèi)。這樣才能保證該線程執(zhí)行過程中會睡眠。
?
例如,在前面的例子中,將一個耗時的操作改為睡眠,以減慢線程的執(zhí)行。可以這么寫:
?
??? public void run() {
??????? for(int i = 0;i<5;i++){
// 很耗時的操作,用來減慢線程的執(zhí)行
//??????????? for(long k= 0; k <100000000;k++);
??????????? try {
??????????????? Thread.sleep(3);
??????????? } catch (InterruptedException e) {
??????????????? e.printStackTrace();? .
??????????? }

??????????? System.out.println(this.getName()+" :"+i);
??????? }
??? }
?
運行結(jié)果:
        阿三 :0 
李四 :0 
阿三 :1 
阿三 :2 
阿三 :3 
李四 :1 
李四 :2 
阿三 :4 
李四 :3 
李四 :4 

Process finished with exit code 0
      
?
這樣,線程在每次執(zhí)行過程中,總會睡眠3毫秒,睡眠了,其他的線程就有機會執(zhí)行了。
?
注意:
1、線程睡眠是幫助所有線程獲得運行機會的最好方法。
2、線程睡眠到期自動蘇醒,并返回到可運行狀態(tài),不是運行狀態(tài)。sleep()中指定的時間是線程不會運行的最短時間。因此,sleep()方法不能保證該線程睡眠到期后就開始執(zhí)行。
3、sleep()是靜態(tài)方法,只能控制當(dāng)前正在運行的線程。
下面給個例子:
          /** 
* 一個計數(shù)器,計數(shù)到100,在每個數(shù)字之間暫停1秒,每隔10個數(shù)字輸出一個字符串 
* 
* @author leizhimin 2008-9-14 9:53:49 
*/ 
public class MyThread extends Thread { 

    public void run() { 
        for (int i = 0; i < 100; i++) { 
            if ((i) % 10 == 0) { 
                System.out.println("-------" + i); 
            } 
            System.out.print(i); 
            try { 
                Thread.sleep(1); 
                System.out.print("    線程睡眠1毫秒!\n"); 
            } catch (InterruptedException e) { 
                e.printStackTrace(); 
            } 
        } 
    } 

    public static void main(String[] args) { 
        new MyThread().start(); 
    } 
} 

        
?
          -------0 
0    線程睡眠1毫秒! 
1    線程睡眠1毫秒! 
2    線程睡眠1毫秒! 
3    線程睡眠1毫秒! 
4    線程睡眠1毫秒! 
5    線程睡眠1毫秒! 
6    線程睡眠1毫秒! 
7    線程睡眠1毫秒! 
8    線程睡眠1毫秒! 
9    線程睡眠1毫秒! 
-------10 
10    線程睡眠1毫秒! 
11    線程睡眠1毫秒! 
12    線程睡眠1毫秒! 
13    線程睡眠1毫秒! 
14    線程睡眠1毫秒! 
15    線程睡眠1毫秒! 
16    線程睡眠1毫秒! 
17    線程睡眠1毫秒! 
18    線程睡眠1毫秒! 
19    線程睡眠1毫秒! 
-------20 
20    線程睡眠1毫秒! 
21    線程睡眠1毫秒! 
22    線程睡眠1毫秒! 
23    線程睡眠1毫秒! 
24    線程睡眠1毫秒! 
25    線程睡眠1毫秒! 
26    線程睡眠1毫秒! 
27    線程睡眠1毫秒! 
28    線程睡眠1毫秒! 
29    線程睡眠1毫秒! 
-------30 
30    線程睡眠1毫秒! 
31    線程睡眠1毫秒! 
32    線程睡眠1毫秒! 
33    線程睡眠1毫秒! 
34    線程睡眠1毫秒! 
35    線程睡眠1毫秒! 
36    線程睡眠1毫秒! 
37    線程睡眠1毫秒! 
38    線程睡眠1毫秒! 
39    線程睡眠1毫秒! 
-------40 
40    線程睡眠1毫秒! 
41    線程睡眠1毫秒! 
42    線程睡眠1毫秒! 
43    線程睡眠1毫秒! 
44    線程睡眠1毫秒! 
45    線程睡眠1毫秒! 
46    線程睡眠1毫秒! 
47    線程睡眠1毫秒! 
48    線程睡眠1毫秒! 
49    線程睡眠1毫秒! 
-------50 
50    線程睡眠1毫秒! 
51    線程睡眠1毫秒! 
52    線程睡眠1毫秒! 
53    線程睡眠1毫秒! 
54    線程睡眠1毫秒! 
55    線程睡眠1毫秒! 
56    線程睡眠1毫秒! 
57    線程睡眠1毫秒! 
58    線程睡眠1毫秒! 
59    線程睡眠1毫秒! 
-------60 
60    線程睡眠1毫秒! 
61    線程睡眠1毫秒! 
62    線程睡眠1毫秒! 
63    線程睡眠1毫秒! 
64    線程睡眠1毫秒! 
65    線程睡眠1毫秒! 
66    線程睡眠1毫秒! 
67    線程睡眠1毫秒! 
68    線程睡眠1毫秒! 
69    線程睡眠1毫秒! 
-------70 
70    線程睡眠1毫秒! 
71    線程睡眠1毫秒! 
72    線程睡眠1毫秒! 
73    線程睡眠1毫秒! 
74    線程睡眠1毫秒! 
75    線程睡眠1毫秒! 
76    線程睡眠1毫秒! 
77    線程睡眠1毫秒! 
78    線程睡眠1毫秒! 
79    線程睡眠1毫秒! 
-------80 
80    線程睡眠1毫秒! 
81    線程睡眠1毫秒! 
82    線程睡眠1毫秒! 
83    線程睡眠1毫秒! 
84    線程睡眠1毫秒! 
85    線程睡眠1毫秒! 
86    線程睡眠1毫秒! 
87    線程睡眠1毫秒! 
88    線程睡眠1毫秒! 
89    線程睡眠1毫秒! 
-------90 
90    線程睡眠1毫秒! 
91    線程睡眠1毫秒! 
92    線程睡眠1毫秒! 
93    線程睡眠1毫秒! 
94    線程睡眠1毫秒! 
95    線程睡眠1毫秒! 
96    線程睡眠1毫秒! 
97    線程睡眠1毫秒! 
98    線程睡眠1毫秒! 
99    線程睡眠1毫秒! 

Process finished with exit code 0
        
?2、線程的優(yōu)先級和線程讓步y(tǒng)ield()
線程的讓步是通過Thread. yield ()來實現(xiàn)的。yield()方法的作用是:暫停當(dāng)前正在執(zhí)行的線程對象,并執(zhí)行其他線程。
?
要理解yield(),必須了解線程的優(yōu)先級的概念。線程總是存在優(yōu)先級,優(yōu)先級范圍在1~10之間。JVM線程調(diào)度程序是基于優(yōu)先級的搶先調(diào)度機制。在大多數(shù)情況下,當(dāng)前運行的線程優(yōu)先級將大于或等于線程池中任何線程的優(yōu)先級。但這僅僅是大多數(shù)情況。
?
注意:當(dāng)設(shè)計多線程應(yīng)用程序的時候,一定不要依賴于線程的優(yōu)先級。因為線程調(diào)度優(yōu)先級操作是沒有保障的,只能把線程優(yōu)先級作用作為一種提高程序效率的方法,但是要保證程序不依賴這種操作。
?
當(dāng)線程池中線程都具有相同的優(yōu)先級,調(diào)度程序的JVM實現(xiàn)自由選擇它喜歡的線程。這時候調(diào)度程序的操作有兩種可能:一是選擇一個線程運行,直到它阻塞或者運行完成為止。二是時間分片,為池內(nèi)的每個線程提供均等的運行機會。
?
設(shè)置線程的優(yōu)先級:線程默認(rèn)的優(yōu)先級是創(chuàng)建它的執(zhí)行線程的優(yōu)先級。可以通過setPriority(int newPriority)更改線程的優(yōu)先級。例如:
??????? Thread t = new MyThread();
??????? t.setPriority(8);
??????? t.start();
線程優(yōu)先級為1~10之間的正整數(shù),JVM從不會改變一個線程的優(yōu)先級。然而,1~10之間的值是沒有保證的。一些JVM可能不能識別10個不同的值,而將這些優(yōu)先級進行每兩個或多個合并,變成少于10個的優(yōu)先級,則兩個或多個優(yōu)先級的線程可能被映射為一個優(yōu)先級。
?
線程默認(rèn)優(yōu)先級是5,Thread類中有三個常量,定義線程優(yōu)先級范圍:
static int MAX_PRIORITY
????????? 線程可以具有的最高優(yōu)先級。
static int MIN_PRIORITY
????????? 線程可以具有的最低優(yōu)先級。
static int NORM_PRIORITY
????????? 分配給線程的默認(rèn)優(yōu)先級。
?
3、Thread.yield()方法
?
Thread.yield()方法作用是:暫停當(dāng)前正在執(zhí)行的線程對象,并執(zhí)行其他線程。
yield()應(yīng)該做的是讓當(dāng)前運行線程回到可運行狀態(tài),以允許具有相同優(yōu)先級的其他線程獲得運行機會。因此,使用yield()的目的是讓相同優(yōu)先級的線程之間能適當(dāng)?shù)妮嗈D(zhuǎn)執(zhí)行。但是,實際中無法保證yield()達(dá)到讓步目的,因為讓步的線程還有可能被線程調(diào)度程序再次選中。
結(jié)論:yield()從未導(dǎo)致線程轉(zhuǎn)到等待/睡眠/阻塞狀態(tài)。在大多數(shù)情況下,yield()將導(dǎo)致線程從運行狀態(tài)轉(zhuǎn)到可運行狀態(tài),但有可能沒有效果。
?
4、join()方法
?
Thread的非靜態(tài)方法join()讓一個線程B“加入”到另外一個線程A的尾部。在A執(zhí)行完畢之前,B不能工作。例如:
??????? Thread t = new MyThread();
??????? t.start();
??????? t.join();
另外,join()方法還有帶超時限制的重載版本。 例如t.join(5000);則讓線程等待5000毫秒,如果超過這個時間,則停止等待,變?yōu)榭蛇\行狀態(tài)。
?
線程的加入join()對線程棧導(dǎo)致的結(jié)果是線程棧發(fā)生了變化,當(dāng)然這些變化都是瞬時的。下面給示意圖:
小結(jié)
到目前位置,介紹了線程離開運行狀態(tài)的3種方法:
1、調(diào)用Thread.sleep():使當(dāng)前線程睡眠至少多少毫秒(盡管它可能在指定的時間之前被中斷)。
2、調(diào)用Thread.yield():不能保障太多事情,盡管通常它會讓當(dāng)前運行線程回到可運行性狀態(tài),使得有相同優(yōu)先級的線程有機會執(zhí)行。
3、調(diào)用join()方法:保證當(dāng)前線程停止執(zhí)行,直到該線程所加入的線程完成為止。然而,如果它加入的線程沒有存活,則當(dāng)前線程不需要停止。
?
除了以上三種方式外,還有下面幾種特殊情況可能使線程離開運行狀態(tài):
1、線程的run()方法完成。
2、在對象上調(diào)用wait()方法(不是在線程上調(diào)用)。
3、線程不能在對象上獲得鎖定,它正試圖運行該對象的方法代碼。
4、線程調(diào)度程序可以決定將當(dāng)前運行狀態(tài)移動到可運行狀態(tài),以便讓另一個線程獲得運行機會,而不需要任何理由。

Java多線程編程總結(jié)--線程狀態(tài)的轉(zhuǎn)換


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲a网| 亚洲一区无码中文字幕 | 亚洲黄区 | av在线播放网址 | 成人网页 | 777奇米影视色888成人 | 欧美影院推理片免费看 | 欧美日在线 | 日本欧美久久久久免费播放网 | 亚洲 综合 欧美 动漫 丝袜图 | 成人国内精品久久久久影 | 色婷婷精品综合久久狠狠 | 久久亚洲国产欧洲精品一 | 午夜专区 | 9久热这里只有精品视频在线观看 | 亚洲欧美日韩中文综合v日本 | 亚洲国产精品无码AV久久久 | 一区二区三区国产免费 | 日韩中文字幕在线播放 | 黄视频网站免费观看 | 欧美电影大全 | 91免费在线视频 | 91精品国产91久久久久久 | 精品一区二区三区三区 | 日韩国产无矿砖一线二线图 | 日本毛片免费看 | 国产高清免费 | 超碰97av| 综合精品一区 | 亚洲xx站 | 在线观看a视频 | 黄色资源视频 | 日韩在线视频一区 | 亚洲午夜久久久精品影院 | 久久人精品| 欧美日韩一区二区在线 | 欧美日韩精品一区二区在线线 | 欧美精品网站 | 小明永久成人一区二区 | 欧美精品一区二区三区蜜桃视频 | 欧美精品一区二区蜜臀亚洲 |