国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java 線程中斷、線程讓步、線程睡眠、線程合并

2019-11-06 07:41:07
字體:
來源:轉載
供稿:網友

http://blog.csdn.net/ghsau/article/details/17560467

本文來自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/17560467,轉載請注明。       最近在Review線程專欄,修改了諸多之前描述不夠嚴謹的地方,凡是帶有Review標記的文章都是修改過了。本篇文章是插進來的,因為原來沒有寫,現在來看傳統線程描述的不太完整,所以就補上了。理解了線程同步和線程通信之后,再來看本文的知識點就會簡單的多了,本文是做為傳統線程知識點的一個補充。有人會問:JDK5之后有了更完善的處理多線程問題的類(并發包),我們還需要去了解傳統線程嗎?答:需要。在實際開發中,無外乎兩種情況,一個是開發新內容,另一個是維護原有程序。開發新內容可以使用新的技術手段,但是我們不能保證原有程序是用什么實現的,所以我們需要了解原有的。另外一點,了解傳統線程的工作原理,使我們在使用并發包時更加得心應手。

線程中斷

       線程中斷涉及到三個方法,如下:
voidinterrupt()          中斷線程。
static booleaninterrupted()          測試當前線程是否已經中斷。
booleanisInterrupted()          測試線程是否已經中斷。
       interrupt()方法用于中斷線程,通常的理解來看,只要某個線程啟動后,調用了該方法,則該線程不能繼續執行了,來看個小例子:[java] view plain copy PRint?在CODE上查看代碼片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 + "次");          }      }  }   %20 %20 %20 運行后,我們發現,線程t一直在執行,沒有被中斷,原來interrupt()是騙人的,汗!其實interrupt()方法并不是中斷線程的執行,而是為調用該方法的線程對象打上一個標記,設置其中斷狀態為true,通過isInterrupted()方法可以得到這個線程狀態,我們將上面的程序做一個小改動:[java] view%20plain copy print?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 + "次");          }      }  }  

 %20 %20 %20 這樣的話,線程被順利的中斷執行了。很多人實現一個線程類時,都會再加一個flag標記,以便控制線程停止執行,其實完全沒必要,通過線程自身的中斷狀態,就可以完美實現該功能。如果線程在調用%20Object%20類的%20wait()、wait(long)%20或%20wait(long,%20int)%20方法,或者該類的%20join()、join(long)、join(long,%20int)、sleep(long)%20或%20sleep(long,%20int)%20方法過程中受阻,則其中斷狀態將被清除,它還將收到一個%20InterruptedException。%20我們可以捕獲該異常,并且做一些處理。另外,Thread.interrupted()方法是一個靜態方法,它是判斷當前線程的中斷狀態,需要注意的是,線程的中斷狀態會由該方法清除。換句話說,如果連續兩次調用該方法,則第二次調用將返回%20false(在第一次調用已清除了其中斷狀態之后,且第二次調用檢驗完中斷狀態前,當前線程再次中斷的情況除外)。

線程讓步 %20 %20 %20 線程讓步,其方法如下:static voidyield()          暫停當前正在執行的線程對象,并執行其他線程 %20 %20 %20 線程讓步用于正在執行的線程,在某些情況下讓出CPU資源,讓給其它線程執行,來看一個小例子:[java] view%20plain copy print?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();              }          }      }  }   %20 %20 %20 輸出結果略,從輸出結果可以看到,當某個線程(t1或者t2)執行到10次、20次、30次等時,就會馬上切換到另一個線程執行,接下來再交替執行,如此往復。注意,如果存在synchronized線程同步的話,線程讓步不會釋放鎖(監視器對象)

線程睡眠 %20 %20 %20 線程睡眠涉及到兩個方法,如下:static voidsleep(long millis)          在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行)。static voidsleep(long millis,%20int nanos)          在指定的毫秒數加指定的納秒數內讓當前正在執行的線程休眠(暫停執行)。 %20 %20 %20 線程睡眠的過程中,如果是在synchronized線程同步內,是持有鎖(監視器對象)的,也就是說,線程是關門睡覺的,別的線程進不來,來看一個小例子:[java] view%20plain copy print?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() + "計算完成");      }  }   %20 %20 %20 輸出結果:[java] view%20plain copy print?t1準備計算  t1感覺累了,開始睡覺  t1睡醒了,開始計算  t1計算完成  t2準備計算  t2感覺累了,開始睡覺  t2睡醒了,開始計算  t2計算完成  線程合并 %20 %20 %20 線程合并涉及到三個方法,如下: voidjoin()          等待該線程終止。 voidjoin(long millis)          等待該線程終止的時間最長為 millis 毫秒。 voidjoin(long millis,%20int nanos)          等待該線程終止的時間最長為 millis 毫秒%20+ nanos 納秒。 %20 %20 %20 線程合并是優先執行調用該方法的線程,再執行當前線程,來看一個小例子:[java] view%20plain copy print?派生到我的代碼片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
public static final intMAX_PRIORITY10
public static final intMIN_PRIORITY1
public static final intNORM_PRIORITY5
       我們創建線程對象后,如果不顯示的設置優先級的話,默認為5。優先級可以看成一種特權,優先級高的,獲取CPU調度的機會就大,優先級低的,獲取CPU調度的機會就小,這個和我們現實生活很一樣啊,優勝劣汰。線程優先級的示例就不寫了,比較簡單。

wait()和sleep()區別

       區別太大了,但是在Java線程面試題中是很常見的問題,相信你閱讀過本專欄后,能夠輕松的解答,這里不再贅述。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 北碚区| 尉犁县| 临海市| 青川县| 渭南市| 介休市| 铜陵市| 惠水县| 乌拉特后旗| 陇川县| 望奎县| 大同市| 昌图县| 黑山县| 清徐县| 崇仁县| 阳东县| 宝山区| 广昌县| 连云港市| 唐山市| 额敏县| 甘德县| 泊头市| 乌兰浩特市| 长顺县| 三都| 龙泉市| 乌鲁木齐县| 青州市| 邻水| 顺义区| 偏关县| 牡丹江市| 台南市| 大方县| 安顺市| 芮城县| 澄迈县| 镶黄旗| 法库县|