程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java編程那些事兒96——多線程使用示例1

Java編程那些事兒96——多線程使用示例1

編輯:關於JAVA

12.3 多線程使用示例

多線程技術對於初學者來說,是編程思維的一種跳躍,在實際學習時,一定要熟悉線程的基礎知識,掌握線程的實現方式,然後就是開始大量的進行實踐,從實踐中領悟線程編程的奧妙以及實現的原理。

下面通過幾個常見的例子演示多線程的基本使用。

12.3.1 定時炸彈

定時炸彈是在電影中常見的一種裝置,在該部分就使用多線程技術模擬該功能。實現的功能為:在程序啟動以後進行倒計時,當60秒以後程序結束,在程序運行時可以在控制台輸入quit控制線程(炸彈)的暫停。

在該示例程序中,開啟了一個系統線程(main方法所在的線程),該線程的作用是啟動模擬定時炸彈的線程,並且在控制台接受用戶的輸入,並判斷輸入的內容是否為quit,如果是則結束模擬定時炸彈的線程,程序結束。

首先來看一下使用繼承Thread類的方式實現多線程時的代碼示例,代碼如下:

package example1;
import java.io.*;
/**
* 模擬定時炸彈線程
*/
public class TestTimeBomb1 {
 public static void main(String[] args) {
  //創建線程和啟動線程
  TimeBombThread tbt = new TimeBombThread();
  //接受控制台輸入
  BufferedReader br = new BufferedReader(
  new InputStreamReader(System.in));
  String line;
  try{
    while(true){
     System.out.println("輸入quit結束線程:");
     //獲得控制台輸入
     line = br.readLine();
     //判斷是否是quit
     if(line.equals("quit")){
      tbt.stopThread(); //結束線程
      break; //結束循環
     }
    }
  }catch(Exception e){}
 }
}
package example1;
/**
* 使用繼承Thread類的方式模擬定時炸彈邏輯
*/
public class TimeBombThread extends Thread {
 int n;
 boolean isRun;
 public TimeBombThread(){
  n = 60;
  isRun = true;
  start();//啟動線程
 }

 public void run(){
  try{
    while(isRun){
     Thread.sleep(1000); //延遲1秒
     System.out.println("剩余時間:" + n);
     if(n <= 0){
      isRun = false; //結束線程
      System.out.println("炸彈爆炸!");
      break;
     }
     n--; //時間減少1
    }
  }catch(Exception e){}
 }

 public void stopThread(){
  isRun = false;
 }
}

在該示例代碼中,TestTimeBomb1類中包含的是系統線程,在系統線程中啟動模擬定時炸彈的TimeBombThread線程,然後在TestTimeBomb1中接收用戶的控制台輸入,如果輸入的內容是quit則結束線程,程序結束,否則忽略用戶的輸入,繼續等待用戶輸入。按照前面介紹的IO知識,在接收控制台輸入時readLine是阻塞方法,也就是該方法在未獲得用戶輸入時會阻塞系統線程的執行,使系統線程進入到等待狀態,等待用戶輸入。而TimeBombThread實現的邏輯是每隔1秒鐘減少一次數值,並輸出剩余時間,當剩余時間為零時,結束TimeBombThread線程。這樣兩個線程就同時工作了,系統線程等待用戶輸入的同時,模擬定時炸彈的線程繼續執行,這樣程序中就包含了兩個同時執行的流程。

在這裡需要特別說明的是,如何控制線程的結束?在本程序中,使用的是讓線程自然死亡的方式,在實際控制線程時,當線程的run方法執行結束則線程自然死亡,所以在本程序中通過控制isRun變量使得線程可以自然結束,從而釋放線程占用的資源。

同樣的功能也可以使用Timer和TimerTask組合的方式實現,實現的代碼如下所示:

package example1;
import java.io.*;
/**
* 模擬定時炸彈線程
*/
public class TestTimeBomb2 {
 public static void main(String[] args) {
  //創建線程和啟動線程
  TimeBombTimerTask tbtt = new TimeBombTimerTask();
  //接受控制台輸入
  BufferedReader br = new BufferedReader(
  new InputStreamReader(System.in));
  String line;
  try{
    while(true){
     System.out.println("輸入quit結束線程:");
     //獲得控制台輸入
     line = br.readLine();
     //判斷是否是quit
     if(line.equals("quit")){
      tbtt.stopThread(); //結束線程
      break; //結束循環
     }
    }
  }catch(Exception e){}
 }
}
package example1;
import java.util.*;
/**
* 使用Timer和TimerTask組合模擬定時炸彈
*/
public class TimeBombTimerTask extends TimerTask {
 int n;
 Timer t;
 boolean isRun;
 public TimeBombTimerTask(){
  n = 60;
  isRun = true;
  t = new Timer();
  t.schedule(this, 0); //啟動線程
 }

 public void run() {
  try{
    while(isRun){
      Thread.sleep(1000); //延遲1秒
      System.out.println("剩余時間:" + n);
      if(n <= 0){
       stopThread(); //結束線程
       System.out.println("炸彈爆炸!");
       break;  //結束循環
      }
      n--; //時間減少1
    }
  }catch(Exception e){}
 }

 public void stopThread(){
  isRun = false;
  t.cancel();
 }
}

在該示例代碼中,實現的原理和前面的類似,TestTimeBomb2類實現系統線程,功能是啟動模擬定時炸彈的線程,並接收用戶的控制台輸入。而TimeBombTimerTask類實現模擬定時炸彈的線程,在該類內部包含啟動線程的Timer對象,當構造該類的對象時,不僅完成該類的初始化,而且啟動線程。

在控制Timer啟動的線程結束時,首先結束當前的TimerTask線程,然後再調用Timer對象的cancel方法結束Timer對象的線程,這樣才可以真正停止這種方式啟動的線程。

至於使用實現Runnable方式實現線程的方式,和繼承Thread類的實現幾乎一致,讀者可以根據第一種方式的實現獨自進行實現,這裡就不再重復實現了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved