多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

中國最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2

java教程

Java 多線程編程

閱讀 (2226)

Java 多線程編程

Java給多線程編程提供了內置的支持。一個多線程程序包含兩個或多個能并發運行的部分。程序的每一部分都稱作一個線程,并且每個線程定義了一個獨立的執行路徑。

多線程是多任務的一種特別的形式。多線程比多任務需要更小的開銷。

這里定義和線程相關的另一個術語:進程:一個進程包括由操作系統分配的內存空間,包含一個或多個線程。一個線程不能獨立的存在,它必須是進程的一部分。一個進程一直運行,直到所有的非守候線程都結束運行后才能結束。

多線程能滿足程序員編寫非常有效率的程序來達到充分利用CPU的目的,因為CPU的空閑時間能夠保持在最低限度。


一個線程的生命周

線程經過其生命周期的各個階段。下圖顯示了一個線程完整的生命周期。

線程 

  • 新狀態: 一個新產生的線程從新狀態開始了它的生命周期。它保持這個狀態知道程序start這個線程。

  • 運行狀態:當一個新狀態的線程被start以后,線程就變成可運行狀態,一個線程在此狀態下被認為是開始執行其任務

  • 就緒狀態:當一個線程等待另外一個線程執行一個任務的時候,該線程就進入就緒狀態。當另一個線程給就緒狀態的線程發送信號時,該線程才重新切換到運行狀態。

  • 休眠狀態: 由于一個線程的時間片用完了,該線程從運行狀態進入休眠狀態。當時間間隔到期或者等待的時間發生了,該狀態的線程切換到運行狀態。

  • 終止狀態: 一個運行狀態的線程完成任務或者其他終止條件發生,該線程就切換到終止狀態。


線程的優先級

每一個Java線程都有一個優先級,這樣有助于操作系統確定線程的調度順序。Java優先級在MIN_PRIORITY(1)和MAX_PRIORITY(10)之間的范圍內。默認情況下,每一個線程都會分配一個優先級NORM_PRIORITY(5)。

具有較高優先級的線程對程序更重要,并且應該在低優先級的線程之前分配處理器時間。然而,線程優先級不能保證線程執行的順序,而且非常依賴于平臺。


創建一個線程

Java提供了兩種創建線程方法:

  • 通過實現Runable接口;

  • 通過繼承Thread類本身。


通過實現Runnable接口來創建線程

創建一個線程,最簡單的方法是創建一個實現Runnable接口的類。

為了實現Runnable,一個類只需要執行一個方法調用run(),聲明如下:

public void run()

你可以重寫該方法,重要的是理解的run()可以調用其他方法,使用其他類,并聲明變量,就像主線程一樣。

在創建一個實現Runnable接口的類之后,你可以在類中實例化一個線程對象。

Thread定義了幾個構造方法,下面的這個是我們經常使用的:

Thread(Runnable threadOb,String threadName);

這里,threadOb 是一個實現Runnable 接口的類的實例,并且 threadName指定新線程的名字。

新線程創建之后,你調用它的start()方法它才會運行。

void start();

實例

下面是一個創建線程并開始讓它執行的實例:

// 創建一個新的線程
class NewThread implements Runnable {
   Thread t;
   NewThread() {
      // 創建第二個新線程
      t = new Thread(this, "Demo Thread");
      System.out.println("Child thread: " + t);
      t.start(); // 開始線程
   }
  
   // 第二個線程入口
   public void run() {
      try {
         for(int i = 5; i > 0; i--) {
            System.out.println("Child Thread: " + i);
            // 暫停線程
            Thread.sleep(50);
         }
     } catch (InterruptedException e) {
         System.out.println("Child interrupted.");
     }
     System.out.println("Exiting child thread.");
   }
}
 
public class ThreadDemo {
   public static void main(String args[]) {
      new NewThread(); // 創建一個新線程
      try {
         for(int i = 5; i > 0; i--) {
           System.out.println("Main Thread: " + i);
           Thread.sleep(100);
         }
      } catch (InterruptedException e) {
         System.out.println("Main thread interrupted.");
      }
      System.out.println("Main thread exiting.");
   }
}

編譯以上程序運行結果如下:

Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.


通過繼承Thread來創建線程

創建一個線程的第二種方法是創建一個新的類,該類繼承Thread類,然后創建一個該類的實例。

繼承類必須重寫run()方法,該方法是新線程的入口點。它也必須調用start()方法才能執行。

實例

// 通過繼承 Thread 創建線程
class NewThread extends Thread {
   NewThread() {
      // 創建第二個新線程
      super("Demo Thread");
      System.out.println("Child thread: " + this);
      start(); // 開始線程
   }
 
   // 第二個線程入口
   public void run() {
      try {
         for(int i = 5; i > 0; i--) {
            System.out.println("Child Thread: " + i);
                            // 讓線程休眠一會
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Child interrupted.");
      }
      System.out.println("Exiting child thread.");
   }
}
 
public class ExtendThread {
   public static void main(String args[]) {
      new NewThread(); // 創建一個新線程
      try {
         for(int i = 5; i > 0; i--) {
            System.out.println("Main Thread: " + i);
            Thread.sleep(100);
         }
      } catch (InterruptedException e) {
         System.out.println("Main thread interrupted.");
      }
      System.out.println("Main thread exiting.");
   }
}

編譯以上程序運行結果如下:

Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.

Thread 方法

下表列出了Thread類的一些重要方法:

序號方法描述
1public void start()
使該線程開始執行;Java 虛擬機調用該線程的 run 方法。
2public void run()
如果該線程是使用獨立的 Runnable 運行對象構造的,則調用該 Runnable 對象的 run 方法;否則,該方法不執行任何操作并返回。
3public final void setName(String name)
改變線程名稱,使之與參數 name 相同。
4public final void setPriority(int priority)
 更改線程的優先級。
5public final void setDaemon(boolean on)
將該線程標記為守護線程或用戶線程。
6public final void join(long millisec)
等待該線程終止的時間最長為 millis 毫秒。
7public void interrupt()
中斷線程。
8public final boolean isAlive()
測試線程是否處于活動狀態。

測試線程是否處于活動狀態。 上述方法是被Thread對象調用的。下面的方法是Thread類的靜態方法。

序號方法描述
1public static void yield()
暫停當前正在執行的線程對象,并執行其他線程。
2public static void sleep(long millisec)
在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和調度程序精度和準確性的影響。
3public static boolean holdsLock(Object x)
當且僅當當前線程在指定的對象上保持監視器鎖時,才返回 true。
4public static Thread currentThread()
返回對當前正在執行的線程對象的引用。
5public static void dumpStack()
將當前線程的堆棧跟蹤打印至標準錯誤流。

實例

如下的ThreadClassDemo 程序演示了Thread類的一些方法:

// 文件名 : DisplayMessage.java
// 通過實現 Runnable 接口創建線程
public class DisplayMessage implements Runnable
{
   private String message;
   public DisplayMessage(String message)
   {
      this.message = message;
   }
   public void run()
   {
      while(true)
      {
         System.out.println(message);
      }
   }
}

// 文件名 : GuessANumber.java
// 通過繼承 Thread 類創建線程

public class GuessANumber extends Thread
{
   private int number;
   public GuessANumber(int number)
   {
      this.number = number;
   }
   public void run()
   {
      int counter = 0;
      int guess = 0;
      do
      {
          guess = (int) (Math.random() * 100 + 1);
          System.out.println(this.getName()
                       + " guesses " + guess);
          counter++;
      }while(guess != number);
      System.out.println("** Correct! " + this.getName()
                       + " in " + counter + " guesses.**");
   }
}

// 文件名 : ThreadClassDemo.java
public class ThreadClassDemo
{
   public static void main(String [] args)
   {
      Runnable hello = new DisplayMessage("Hello");
      Thread thread1 = new Thread(hello);
      thread1.setDaemon(true);
      thread1.setName("hello");
      System.out.println("Starting hello thread...");
      thread1.start();
     
      Runnable bye = new DisplayMessage("Goodbye");
      Thread thread2 = new Thread(bye);
      thread2.setPriority(Thread.MIN_PRIORITY);
      thread2.setDaemon(true);
      System.out.println("Starting goodbye thread...");
      thread2.start();
 
      System.out.println("Starting thread3...");
      Thread thread3 = new GuessANumber(27);
      thread3.start();
      try
      {
         thread3.join();
      }catch(InterruptedException e)
      {
         System.out.println("Thread interrupted.");
      }
      System.out.println("Starting thread4...");
      Thread thread4 = new GuessANumber(75);
     
           thread4.start();
      System.out.println("main() is ending...");
   }
}

運行結果如下,每一次運行的結果都不一樣。

Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Starting thread3...
Hello
Hello
Starting thread4...
Hello
Hello
main() is ending...

線程的幾個主要概念:

在多線程編程時,你需要了解以下幾個概念:

  • 線程同步

  • 線程間通信

  • 線程死鎖

  • 線程控制:掛起、停止和恢復


多線程的使用

有效利用多線程的關鍵是理解程序是并發執行而不是串行執行的。例如:程序中有兩個子系統需要并發執行,這時候就需要利用多線程編程。

通過對多線程的使用,可以編寫出非常高效的程序。不過請注意,如果你創建太多的線程,程序執行的效率實際上是降低了,而不是提升了。

請記住,上下文的切換開銷也很重要,如果你創建了太多的線程,CPU花費在上下文的切換的時間將多于執行程序的時間!

關閉
程序員人生
主站蜘蛛池模板: 日产免费线路一区二区三区 | 黑人双渗透| 午夜一区二区三区 | www啪| 成人免费毛片一区二区三区 | 欧美高清揄拍自拍视频网站 | 欧美猛黑又粗又长xxxx乱 | 亚洲国产欧美久久香综合 | 中文字幕一区二区三区乱码 | 最近免费中文字幕大全高清大全1 | 免费视频中文字幕 | 欧美成人午夜在线全部免费 | 欧美色碰碰碰免费观看长视频 | 亚洲图片国产日韩欧美 | 亚洲a网站 | 欧美亚洲 尤物久久 综合精品 | 91精品国产人成网站 | 国产三级精品三级在线观看 | 最近最新中文字幕免费的一页 | 国产在线不卡一区 | 日韩欧美亚洲综合一区二区 | 国产精品一区二区免费 | 男人午夜视频 | 伊人电院网 | 久久久久久久尹人综合网亚洲 | 黄色jizz| 2020国产精品自拍 | 日韩国产欧美在线观看一区二区 | 宇都宫紫苑乳在线观看 | 国产欧美亚洲精品a | 亚洲免费二区 | 亚洲爽爽 | 国产成+人+综合+亚洲 欧美 | 久久精品成人免费网站 | 亚洲jizzjizz| 欧美成人看片一区二区三区 | 欧美激情区 | 欧美一区二区三区成人看不卡 | 久久久毛片免费全部播放 | 97婷婷色| 亚洲精品人成无码中文毛片 |