首頁 > Java > java教程 > 主體

java線程

伊谢尔伦
發布: 2016-12-10 09:50:44
原創
1223 人瀏覽過

1,  Java中編寫多執行緒程式和其他的程式語言相比容易很多。主要透過Runnable介面和Thread類別來實現。

publicclassSimpleRunnable implements Runnable{
   private String message;
   publicstaticvoid main(String[] args) {
      SimpleRunnabler1 = new SimpleRunnable("Hello");
      Threadt1 = new Thread(r1);
      t1.start();
      for(;;){
         System.out.println("Bye-bye");
      }
   }
   public SimpleRunnable(String message){
      this.message = message;
   }
   @Override
   publicvoid run() {
      for(;;){
         System.out.println(message);
      }
   }
}
登入後複製

以上,透過繼承於Runable介面實作run()來實作多線程,透過Thread來實作虛擬CPU,讓執行緒r1在獨立的執行緒中運行。事實上,該線程和主線程並不是完全的獨立運行的線程,而是r1線程和主線程輪番切換運行,只是切換的運行速度特別快,看起來像是兩個線程獨立運行。

2,  執行緒的切換,根據不同的作業系統而有所不同:

一種是排隊機制,如果一個執行緒搶得了CPU,直到該執行緒運行結束,或被動停止才推出。

一種是透過優先權模式,優先權最高的執行緒優先權搶到CPU。

一種是時間片,每個執行緒擁有公平的時間片,當一個執行緒運行完時間片後退出,其他的執行緒擁有公平的機會搶佔CPU。

Java的執行緒採用基於優先權和時間片綜合的方式,具體實現根據運行的作業系統而有所不同。比如說當一個線程時間片運行完後退出並將優先權降一級,然後排序優先權比較高的線程搶佔CPU,如果運行的過程中來了一個優先級更高的線程,則會搶佔當前的CPU。

3,  線程運行狀態:

線程停止(Pause)包括,sleep(),wait(),suspend(),I/O blocking

線程重啟(Run)包括,sleep time-out,notify() ,resume(),I/O finished

線程終止,stop()

線程等待,join()

線程主動讓出CPU,yield()

以上suspend(),resume(),stop()都已過時,不再建議使用。

4,  其中sleep()函數是static的,是屬於類別的函數,而不是物件。這個函數將使呼叫的執行緒暫停一定時間,而不是某一個其他的執行緒停止。如下

publicstaticvoidmain(String[] args)throwsException {
      SimpleRunnabler1 = new SimpleRunnable("Hello");
      Threadt1 = newThread(r1);
      t1.start();
      for(inti = 0; i < 10; i++){
         System.out.println("Bye-bye");
      }
      t1.sleep(10000);
      t1.stop();
}
登入後複製

以上程式碼是讓主執行緒停止10秒鐘,而不是讓t1停止10秒鐘。另外sleep()讓執行緒暫停的時間是個模糊值,以上理論將使主執行緒暫停10秒鐘,但由於執行緒切換的不確定性,導致主執行緒並不是精確的暫停10秒鐘。

5,  另外一個static的函數是yield(),他表示目前正在運行的線程主動讓出CPU,該函數也是僅能作用於當前線程類似於以上sleep()函數。

6,  程式設計是為了追求高效率的結果,採用多執行緒。但是多執行緒運行是很難預測的,因此我們會採取一定的方法,讓多執行緒的運行結果盡量可預測。

class Thread1 extends Thread{
   @Override
   publicvoid run(){
      try{
         System.out.println("thread1 start");
         sleep(10000);                  // <3>
         System.out.println("thread1 finish");//<4>
      }catch(Exception e){
      }
   }
}
class Thread2 extends Thread{
   @Override
   publicvoid run(){
      try{
         System.out.println("thread2 start");
         suspend();                  // <2>
         System.out.println("thread2 finish");// <7>
      }catch(Exception e){
      }
   }
}
publicclassThreadTest {
 
   publicstaticvoid main(String[] args) {
      Threadt1 = new Thread1();
      Thread2t2 = new Thread2();
      t1.start();
      t2.start();
      try{
         System.out.println("s1");
         t1.join();                  // <1>
         System.out.println("s2");      // <5>
         t2.resume();                //<6>
         System.out.println("s3");      // <8>
         t2.join();                  // <9>
      }catch(Exception e){
      }
      System.out.println("s4");         // <10>
   }
}
登入後複製

以上運行其中一次的運行結果為:

thread1 start

thread2 start

s1

thread1 finish

s2

但是並不是每次都得到這樣的結果。但是也有一部分是可預測的。哪些是可預測的?哪些是不可預測的?

(1)       前三行一定會佔據前三行,由於的程式碼使主執行緒停止,等待執行緒t1結束,而t1執行緒在處使執行緒暫停10秒鐘,同時處程式碼是線程t2處於掛起狀態,知道有程式碼喚醒該線程,否則該線程就會一直處於阻塞狀態。但是前三行的輸出順序是無法預測的。

(2)      第四行一定會在第四行,當t1休眠結束後,首先運行處程式碼

(3)      第五行一定會在第五行,當t1執行結束後,主執行緒取得CPU開始運行程式碼

(4)      第六行和第七行的位置可能會互換,當程式碼喚醒執行緒t2後從開始運行,同時主執行緒繼續運行

(5)      最後一行一定會在最後一行。在暫停主線程,等待t2運行結束,運行輸出最後一行,主線程結束退出。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板