熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

java線程簡介(線程的生命)

2013-11-23 19:49:59  來源: Java高級技術 

  創建線程
  
  
  在 Java 程序中創建線程有幾種方法每個 Java 程序至少包含一個線程主線程其它線程都是通過 Thread 構造器或實例化繼承類 Thread 的類來創建的
  
  Java 線程可以通過直接實例化 Thread 對象或實例化繼承 Thread 的對象來創建其它線程在線程基礎中的示例(其中我們在十秒鐘之內計算盡量多的素數)中我們通過實例化 CalculatePrimes 類型的對象(它繼承了 Thread)創建了一個線程
  
  當我們討論 Java 程序中的線程時也許會提到兩個相關實體完成工作的實際線程或代表線程的 Thread 對象正在運行的線程通常是由操作系統創建的Thread 對象是由 Java VM 創建的作為控制相關線程的一種方式
  
  創建線程和啟動線程並不相同
  
  
  在一個線程對新線程的 Thread 對象調用 start() 方法之前這個新線程並沒有真正開始執行Thread 對象在其線程真正啟動之前就已經存在了而且其線程退出之後仍然存在這可以讓您控制或獲取關於已創建的線程的信息即使線程還沒有啟動或已經完成了
  
  通常在構造器中通過 start() 啟動線程並不是好主意這樣做會把部分構造的對象暴露給新的線程如果對象擁有一個線程那麼它應該提供一個啟動該線程的 start() 或 init() 方法而不是從構造器中啟動它
  
  結束線程
  
  
  線程會以以下三種方式之一結束
  
  線程到達其 run() 方法的末尾
  
  
  線程拋出一個未捕獲到的 Exception 或 Error
  
  
  另一個線程調用一個棄用的 stop() 方法棄用是指這些方法仍然存在但是您不應該在新代碼中使用它們並且應該盡量從現有代碼中除去它們
  當 Java 程序中的所有線程都完成時程序就退出了
  
  加入線程
  
  Thread API 包含了等待另一個線程完成的方法join() 方法當調用 Threadjoin() 時調用線程將阻塞直到目標線程完成為止
  
  Threadjoin() 通常由使用線程的程序使用以將大問題劃分成許多小問題每個小問題分配一個線程本章結尾處的示例創建了十個線程啟動它們然後使用 Threadjoin() 等待它們全部完成
  
  調度
  
  
  除了何時使用 Threadjoin() 和 Objectwait() 外線程調度和執行的計時是不確定的如果兩個線程同時運行而且都不等待您必須假設在任何兩個指令之間其它線程都可以運行並修改程序變量如果線程要訪問其它線程可以看見的變量如從靜態字段(全局變量)直接或間接引用的數據則必須使用同步以確保數據一致性
  
  在以下的簡單示例中我們將創建並啟動兩個線程每個線程都打印兩行到 Systemout
  
  
  public class TwoThreads {
  
   public static class Thread extends Thread {
   public void run() {
   Systemoutprintln(A);
   Systemoutprintln(B);
   }
   }
  
   public static class Thread extends Thread {
   public void run() {
   Systemoutprintln();
   Systemoutprintln();
   }
   }
  
   public static void main(String[] args) {
   new Thread()start();
   new Thread()start();
   }
  }
  
  
  我們並不知道這些行按什麼順序執行只知道之前打印以及AB之前打印輸出可能是以下結果中的任何一種
  
   A B
   A B
   A B
  A B
  A B
  A B
  不僅不同機器之間的結果可能不同而且在同一機器上多次運行同一程序也可能生成不同結果永遠不要假設一個線程會在另一個線程之前執行某些操作除非您已經使用了同步以強制一個特定的執行順序
  
  休眠
  
  
  Thread API 包含了一個 sleep() 方法它將使當前線程進入等待狀態直到過了一段指定時間或者直到另一個線程對當前線程的 Thread 對象調用了 Threadinterrupt()從而中斷了線程當過了指定時間後線程又將變成可運行的並且回到調度程序的可運行線程隊列中
  
  如果線程是由對 Threadinterrupt() 的調用而中斷的那麼休眠的線程會拋出 InterruptedException這樣線程就知道它是由中斷喚醒的就不必查看計時器是否過期
  
  Threadyield() 方法就象 Threadsleep() 一樣但它並不引起休眠而只是暫停當前線程片刻這樣其它線程就可以運行了在大多數實現中當較高優先級的線程調用 Threadyield() 時較低優先級的線程就不會運行
  
  CalculatePrimes 示例使用了一個後台線程計算素數然後休眠十秒鐘當計時器過期後它就會設置一個標志表示已經過了十秒
  
  守護程序線程
  
  
  我們提到過當 Java 程序的所有線程都完成時該程序就退出但這並不完全正確隱藏的系統線程如垃圾收集線程和由 JVM 創建的其它線程會怎麼樣?我們沒有辦法停止這些線程如果那些線程正在運行那麼 Java 程序怎麼退出呢?
  
  這些系統線程稱作守護程序線程Java 程序實際上是在它的所有非守護程序線程完成後退出的
  
  任何線程都可以變成守護程序線程可以通過調用 ThreadsetDaemon() 方法來指明某個線程是守護程序線程您也許想要使用守護程序線程作為在程序中創建的後台線程如計時器線程或其它延遲的事件線程只有當其它非守護程序線程正在運行時這些線程才有用
  
  示例用多個線程分解大任務
  
  
  在這個示例中TenThreads 顯示了一個創建了十個線程的程序每個線程都執行一部分工作該程序等待所有線程全部完成然後收集結果
  
  
  /**
   * Creates ten threads to search for the maximum value of a large matrix
   * Each thread searches one portion of the matrix
   */
  public class TenThreads {
  
   private static class WorkerThread extends Thread {
   int max = IntegerMIN_VALUE;
   int[] ourArray;
  
   public WorkerThread(int[] ourArray) {
   thisourArray = ourArray;
   }
  
   // Find the maximum value in our particular piece of the array
   public void run() {
   for (int i = ; i < ourArray.length; i++)
   max = Math.max(max, ourArray[i]);
   }
  
   public int getMax() {
   return max;
   }
   }
  
   public static void main(String[] args) {
   WorkerThread[] threads = new WorkerThread[10];
   int[][] bigMatrix = getBigHairyMatrix();
   int max = Integer.MIN_VALUE;
  
   // Give each thread a slice of the matrix to work with
   for (int i=0; i < 10; i++) {
   threads[i] = new WorkerThread(bigMatrix[i]);
   threads[i].start();
   }
  
   // Wait for each thread to finish
   try {
   for (int i=0; i < 10; i++) {
   threads[i].join();
   max = Math.max(max, threads[i].getMax());
   }
   }
   catch (InterruptedException e) {
   // fall through
   }
  
   System.out.println("Maximum value was " + max);
   }
  }
  
  9、小結
  
  
  就象程序一樣,線程有生命周期:它們啟動、執行,然後完成。TW.winGWiT.CoM一個程序或進程也許包含多個線程,而這些線程看來互相單獨地執行。
  
  線程是通過實例化 Thread 對象或實例化繼承 Thread 的對象來創建的,但在對新的 Thread 對象調用 start() 方法之前,這個線程並沒有開始執行。當線程運行到其 run() 方法的末尾或拋出未經處理的異常時,它們就結束了。
  
  sleep() 方法可以用於等待一段特定時間;而 join() 方法可能用於等到另一個線程完成。

From:http://tw.wingwit.com/Article/program/Java/gj/201311/27530.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.