<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Java線程(四):線程中斷、線程讓步、線程睡眠、線程合并 最近在Review線程專欄,修改了諸多之前描述不夠嚴謹的地方,凡是帶有Review標記的文章都是修改過了。本篇文章是插進來的,因為原來沒有寫,現在來看傳統線程描述的不太完整,所以就補上了。理解了線程同步和線程通信之后,再來看本文的知識點就會簡單的多了,本文是做為傳統線程知識點的一個補充。有人會問:JDK5之后有了更完善的處理多線程問題的類(并發包),我們還需要去了解傳統線程嗎?答:需要。在實際開發中,無外乎兩種情況,一個是開發新內容,另一個是維護原有程序。開發新內容可以使用新的技術手段,但是我們不能保證原有程序是用什么實現的,所以我們需要了解原有的。另外一點,了解傳統線程的工作原理,使我們在使用并發包時更加得心應手。 ## 線程中斷 線程中斷涉及到三個方法,如下: | `void` | `[interrupt](http://blog.csdn.net/ghsau/article/details/17560467)**()`中斷線程。 | |---|---|---| | `static?boolean` | `[interrupted](http://blog.csdn.net/ghsau/article/details/17560467)**()`測試當前線程是否已經中斷。 | | `boolean` | `[isInterrupted](http://blog.csdn.net/ghsau/article/details/17560467)**()`測試線程是否已經中斷。 | interrupt()方法用于中斷線程,通常的理解來看,只要某個線程啟動后,調用了該方法,則該線程不能繼續執行了,來看個小例子: ~~~ public?class?InterruptTest?{?? ????public?static?void?main(String[]?args)?throws?InterruptedException?{?? ????????MyThread?t?=?new?MyThread("MyThread");?? ????????t.start();?? ????????Thread.sleep(100);//?睡眠100毫秒?? ????????t.interrupt();//?中斷t線程?? ????}?? }?? class?MyThread?extends?Thread?{?? ????int?i?=?0;?? ????public?MyThread(String?name)?{?? ????????super(name);?? ????}?? ????public?void?run()?{?? ????????while(true)?{//?死循環,等待被中斷?? ????????????System.out.println(getName()?+?getId()?+?"執行了"?+?++i?+?"次");?? ????????}?? ????}?? }?? ~~~ 運行后,我們發現,線程t一直在執行,沒有被中斷,原來interrupt()是騙人的,汗!其實interrupt()方法并不是中斷線程的執行,而是為調用該方法的線程對象打上一個標記,設置其中斷狀態為true,通過isInterrupted()方法可以得到這個線程狀態,我們將上面的程序做一個小改動: ~~~ public?class?InterruptTest?{?? ????public?static?void?main(String[]?args)?throws?InterruptedException?{?? ????????MyThread?t?=?new?MyThread("MyThread");?? ????????t.start();?? ????????Thread.sleep(100);//?睡眠100毫秒?? ????????t.interrupt();//?中斷t線程?? ????}?? }?? class?MyThread?extends?Thread?{?? ????int?i?=?0;?? ????public?MyThread(String?name)?{?? ????????super(name);?? ????}?? ????public?void?run()?{?? ????????while(!isInterrupted())?{//?當前線程沒有被中斷,則執行?? ????????????System.out.println(getName()?+?getId()?+?"執行了"?+?++i?+?"次");?? ????????}?? ????}?? }?? ~~~ 這樣的話,線程被順利的中斷執行了。很多人實現一個線程類時,都會再加一個flag標記,以便控制線程停止執行,其實完全沒必要,通過線程自身的中斷狀態,就可以完美實現該功能。如果線程在調用 Object 類的 wait()、wait(long) 或 wait(long, int) 方法,或者該類的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法過程中受阻,則其中斷狀態將被清除,它還將收到一個 InterruptedException。 我們可以捕獲該異常,并且做一些處理。另外,Thread.interrupted()方法是一個靜態方法,它是判斷當前線程的中斷狀態,需要注意的是,線程的中斷狀態會由該方法清除。換句話說,如果連續兩次調用該方法,則第二次調用將返回 false(在第一次調用已清除了其中斷狀態之后,且第二次調用檢驗完中斷狀態前,當前線程再次中斷的情況除外)。 ## 線程讓步 線程讓步,其方法如下: | `static?void` | `[yield](http://blog.csdn.net/ghsau/article/details/17560467)**()`暫停當前正在執行的線程對象,并執行其他線程 | |---|---|---| 線程讓步用于正在執行的線程,在某些情況下讓出CPU資源,讓給其它線程執行,來看一個小例子: ~~~ public?class?YieldTest?{?? ????public?static?void?main(String[]?args)?throws?InterruptedException?{?? ????????//?創建線程對象?? ????????YieldThread?t1?=?new?YieldThread("t1");?? ????????YieldThread?t2?=?new?YieldThread("t2");?? ????????//?啟動線程?? ????????t1.start();?? ????????t2.start();?? ????????//?主線程休眠100毫秒?? ????????Thread.sleep(100);?? ????????//?終止線程?? ????????t1.interrupt();?? ????????t2.interrupt();?? ????}?? }?? class?YieldThread?extends?Thread?{?? ????int?i?=?0;?? ????public?YieldThread(String?name)?{?? ????????super(name);?? ????}?? ????public?void?run()?{?? ????????while(!isInterrupted())?{?? ????????????System.out.println(getName()?+?"執行了"?+?++i?+?"次");?? ????????????if(i?%?10?==?0)?{//?當i能對10整除時,則讓步?? ????????????????Thread.yield();?? ????????????}?? ????????}?? ????}?? }?? ~~~ 輸出結果略,從輸出結果可以看到,當某個線程(t1或者t2)執行到10次、20次、30次等時,就會馬上切換到另一個線程執行,接下來再交替執行,如此往復。**注意,如果存在synchronized線程同步的話,線程讓步不會釋放鎖(監視器對象)**。 ## 線程睡眠 線程睡眠涉及到兩個方法,如下: | `static?void` | `[sleep](http://blog.csdn.net/ghsau/article/details/17560467)**(long?millis)`在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行)。 | |---|---|---| | `static?void` | `[sleep](http://blog.csdn.net/ghsau/article/details/17560467)**(long?millis, int?nanos)`在指定的毫秒數加指定的納秒數內讓當前正在執行的線程休眠(暫停執行)。 | **線程睡眠的過程中,如果是在synchronized線程同步內,是持有鎖(監視器對象)的**,也就是說,線程是關門睡覺的,別的線程進不來,來看一個小例子: ~~~ public?class?SleepTest?{?? ????public?static?void?main(String[]?args)?{?? ????????//?創建共享對象?? ????????Service?service?=?new?Service();?? ????????//?創建線程?? ????????SleepThread?t1?=?new?SleepThread("t1",?service);?? ????????SleepThread?t2?=?new?SleepThread("t2",?service);?? ????????//?啟動線程?? ????????t1.start();?? ????????t2.start();?? ????}?? ?????? }?? class?SleepThread?extends?Thread?{?? ????private?Service?service;?? ????public?SleepThread(String?name,?Service?service)?{?? ????????super(name);?? ????????this.service?=?service;?? ????}?? ????public?void?run()?{?? ????????service.calc();?? ????}?? }?? class?Service?{?? ????public?synchronized?void?calc()?{?? ????????System.out.println(Thread.currentThread().getName()?+?"準備計算");?? ????????System.out.println(Thread.currentThread().getName()?+?"感覺累了,開始睡覺");?? ????????try?{?? ????????????Thread.sleep(10000);//?睡10秒?? ????????}?catch?(InterruptedException?e)?{?? ????????????return;?? ????????}?? ????????System.out.println(Thread.currentThread().getName()?+?"睡醒了,開始計算");?? ????????System.out.println(Thread.currentThread().getName()?+?"計算完成");?? ????}?? }?? ~~~ 輸出結果: ~~~ t1準備計算?? t1感覺累了,開始睡覺?? t1睡醒了,開始計算?? t1計算完成?? t2準備計算?? t2感覺累了,開始睡覺?? t2睡醒了,開始計算?? t2計算完成?? ~~~ ## 線程合并 線程合并涉及到三個方法,如下: | `?void` | `[join](http://blog.csdn.net/ghsau/article/details/17560467)**()`等待該線程終止。 | |---|---|---| | `?void` | `[join](http://blog.csdn.net/ghsau/article/details/17560467)**(long?millis)`等待該線程終止的時間最長為?`millis`?毫秒。 | | `?void` | `[join](http://blog.csdn.net/ghsau/article/details/17560467)**(long?millis, int?nanos)`等待該線程終止的時間最長為?`millis`?毫秒 +?`nanos`?納秒。 | 線程合并是優先執行調用該方法的線程,再執行當前線程,來看一個小例子: ~~~ public?class?JoinTest?{?? ????public?static?void?main(String[]?args)?throws?InterruptedException?{?? ????????JoinThread?t1?=?new?JoinThread("t1");?? ????????JoinThread?t2?=?new?JoinThread("t2");?? ????????t1.start();?? ????????t2.start();?? ????????t1.join();?? ????????t2.join();?? ????????System.out.println("主線程開始執行!");?? ????}?? }?? class?JoinThread?extends?Thread?{?? ????public?JoinThread(String?name)?{?? ????????super(name);?? ????}?? ????public?void?run()?{?? ????????for(int?i?=?1;?i?10;?i++)?? ????????????System.out.println(getName()?+?getId()?+?"執行了"?+?i?+?"次");?? ????}?? }?? ~~~ t1和t2都執行完才繼續主線程的執行,所謂合并,就是等待其它線程執行完,再執行當前線程,執行起來的效果就好像把其它線程合并到當前線程執行一樣。 ## 線程優先級 線程最低優先級為1,最高優先級為10,看起來就有10個級別,但這10個級別能不能和CPU對應上,還未可知,Thread類中提供了優先級的三個常量,如下: | java.lang.[Thread](http://blog.csdn.net/ghsau/article/details/17560467 "java.lang 中的類") | |---|---|---|---| | `public?static?final?int``[MAX_PRIORITY](http://blog.csdn.net/ghsau/article/details/17560467)` | `10` | | `public?static?final?int``[MIN_PRIORITY](http://blog.csdn.net/ghsau/article/details/17560467)` | `1` | | `public?static?final?int``[NORM_PRIORITY](http://blog.csdn.net/ghsau/article/details/17560467)` | `5` | 我們創建線程對象后,如果不顯示的設置優先級的話,默認為5。優先級可以看成一種特權,優先級高的,獲取CPU調度的機會就大,優先級低的,獲取CPU調度的機會就小,這個和我們現實生活很一樣啊,優勝劣汰。線程優先級的示例就不寫了,比較簡單。 ## wait()和sleep()區別 區別太大了,但是在Java線程面試題中是很常見的問題,相信你閱讀過本專欄后,能夠輕松的解答,這里不再贅述。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看