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

Java線程使用入門

編輯:關於JAVA

Java平台從開始就被設計成為多線程環境。在你的主程序執行的時候,其它作業如碎片收集和事件處理則是在後台進行的。本質上,你可以認為這些作業是線程。它們正好是系統管理線程,但是無論如何,它們是線程。線程使你能夠定義相互獨立的作業,彼此之間互不干擾。系統將交換這些作業進或出CPU,這樣(從外部看來)它們好象是同時運行的。

在你需要在你的程序中處理多個作業時,你也可以使用多個進程。這些進程可以是你自己創建的,你也可以操縱系統線程。

你進行這些多作業處理,要使用幾個不同的類或接口:

java.util.Timer類

javax.swing.Timer類

Thread類

Runnable接口

對於簡單的作業,通常需要重復的,你可以使用java.util.Timer類告訴它“每半秒鐘做一次”。注意:大多數系統例程是使用毫秒的。半秒鐘是500毫秒。

你希望Timer實現的任務是在java.util.TimerTask實例中定義的,其中運行的方法包含要執行的任務。這些在Hi類中進行了演示,其中字符串“Hi”重復地被顯示在屏幕上,直到你按Enter鍵。

import java.util.*;
public class Hi {
  public static void main(String args[])
  throws java.io.IOException {
   TimerTask task = new TimerTask() {
   public void run() {
    System.out.println("Hi");
   }
  };
  Timer timer = new Timer();
  timer.schedule(task, 0, 500);
  System.out.println("Press ENTER to stop");
  System.in.read(new byte[10]);
  timer.cancel();
}
}

Java Runtime Environment工作的方式是只要有一個線程在運行,程序就不退出。這樣,當取消被調用,沒有其它線程在運行了,則程序退出。有一些系統線程在運行,如碎片收集程序。這些系統線程也被稱為後台線程。後台線程的存在不影響運行環境被關閉,只有非後台線程保證運行環境不被關閉。

Javax.swing.Timer類與java.util.timer類的工作方式相似,但是有一些差別需要注意。第一,運行的作業被ActionListener接口的實現來定義。第二,作業的執行是在事件處理線程內部進行的,而不象java.util.Timer類是在它的外部。這是很重要的,因為它關系到Swing組件集是如何設計的。

如果你不熟悉Swing,它是一組可以被Java程序使用的圖形組件。Swing被設計程被稱為單線程的。這意味著對Swing類內部內容的訪問必須在單個線程中完成。這個特定的線程是事件處理線程。這樣,例如你想改變Label組件的文字,你不能僅僅調用Jlabel的setText方法。相反,你必須確認setText調用發生在事件處理線程中,而這正是javax.swing.Time類派的上用場的地方。

為了說明這第二種情況,下面的程序顯示一個增加的計數器的值。美半秒鐘計數器的數值增加,並且新的數值被顯示。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Count {
  public static void main(String args[]) {
   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   Container contentPane = frame.getContentPane();
   final JLabel label = new JLabel("", JLabel.CENTER);
   label.setFont(new Font("Serif", Font.PLAIN, 36));
   contentPane.add(label, BorderLayout.CENTER);
   ActionListener listener = new ActionListener() {
    int count = 0;
    public void actionPerformed(ActionEvent e) {
     count++;
     label.setText(Integer.toString(count));
    }
   };
   Timer timer = new Timer(500, listener);
   timer.start();
   frame.setSize(300, 100);
   frame.show();
  }
}

上述程序的結果是:

萬一你要做的不是一個簡單的重復作業,java.lang.Thread類就派上了用場。它允許你自己控制基本功能。通過創建Thread的一個子類,你可以使你的系統脫離,並進行一個長時間運行的作業,如從網絡上讀取一個文件,而不阻礙你的其它程序的運行。這種長時間運行的作業將在run方法中定義。

第二種方式是創建Thread類的子類並在子類中實現run方法,或在實現runnable的類中實現run方法,並將這個實現傳遞給Thread的構造函數。

你可能會問有什麼區別。Java編程語言僅支持單一繼承。如果你設計的調用是除了Thread以外的其它類,你可以是你的類實現Runnable,而它可以是你的作業被執行。否則,你定義Thread的子類來運行你的Run方法,在處理過程中不再添加其它操作。

對於創建Thread子類的第三種情況,下面的程序生成了一個新的線程來計算一個特定URL的字符數,這個URL是通過命令行傳遞進來的。在這進行過程之中,實現Runnable的第四種情況被演示,打印出重復的消息。注意在實現Runnable的這後一種情況下,你必須提供重復消息的代碼。你必須同時sleep,以分配時間並完成操作。在兩種情況下,與使用Timer相比較。這段程序的最後一部分包含有你從命令行讀取命令以觸發程序結束。注意在系統讀取URL並打印消息的同時,你總可以按Enter鍵結束程序。

import java.io.*;
import java.net.*;
public class Both {
  public static void main(String args[]) {
   final String urlString = args[0];
   final String message = args[1];
   Thread thread1 = new Thread() {
    public void run() {
     try {
      URL url = new URL(urlString);
      URLConnection connection = url.openConnection();
      InputStreamReader isr = new InputStreamReader(
       connection.getInputStream());
      BufferedReader reader = new BufferedReader(isr);
      int count = 0;
      while (reader.read() != -1) {
        count++;
      }
      System.out.println("Size is : " + count);
      reader.close();
     } catch (MalformedURLException e) {
      System.err.println("Bad URL: "+ urlString);
     } catch (IOException e) {
      System.err.println("I/O Problems");
     }
    }
   };
   thread1.start();
   Runnable runnable = new Runnable() {
    public void run() {
     while(true) {
      System.out.println(message);
      try {
       Thread.sleep(500);
      } catch (InterruptedException e) {
      }
     }
    }
   };
   Thread thread2 = new Thread(runnable);
   thread2.start();
   try {
    System.out.println("Press ENTER to stop");
    System.in.read(new byte[10]);
   } catch (IOException e) {
   System.out.println("I/O problems");
  }
  System.exit(0);
  }
}

為有多種方式來處理線程,你選用哪種技術取決於你和你面臨的條件。要成為一個有效的Java編程人員,盡管你通常不必學習Java編程語言的所有內容和核心庫,但是線程是一個例外。你越早了解線程如何工作和如何使用線程,你將越早了解Java程序如何工作和交互。

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