Thread類與Runnable介面

來源:互聯網
上載者:User

  Thread類與Runnable介面

   

1.繼承Thread類並重載run方法

Thread類:是專門用來建立線程和對線程進行操作的類。Thread中定義了許多方法對線程進行操作。

Thread類在預設情況下run方法是空的。可以通過繼承Thread類並重寫Thread類的run方法實現使用者線程。

總體結構如下:
public class MyThread extends Thread {
public void run() {
… …
}
}

MyThread t = new MyThread();
t. start();

見例題:TwoThreadsTest.java

TwoThreadsTest.java:該例子示範了如何通過繼承Thread的方法實現線程。該例子同時啟動了兩個線程。請運行之,注意運行結果
class TwoThreadsTest {
public static void main (String args[]) {
new SimpleThread("Jamaica").start();
new SimpleThread("Fiji").start();
}
}

class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}

在這個例子中,類 TwoThreadsTest的main( )方法中構造了兩個 SimpleThread類的線程,一個稱為"Jamaica",另一個為 " Fiji ",並在構造後馬上就調用了start( )方法來啟動這兩個線程。
類SimpleThread是類Thread的子類,它首先定義了一個構造方法,其中自變數為字串類型,例如上面的" Fiji ", 它的作用就是給線程取名。類SimpleThread中的第二個方法是run( )方法,它覆蓋了類Thread中的run( )方法。run( )方法中是一個10次的迴圈,每次迴圈中顯示迴圈的次數和當前正啟動並執行線程的名稱,然後睡眠一個隨機產生的時間間隔。在迴圈結束後,就顯示"DONE!"及線程名。

下面我們來看一下運行結果:

0 Jamaica
0 Fiji
1 Fiji
1 Jamaica
2 Jamaica
2 Fiji
3 Fiji
3 Jamaica
4 Jamaica
4 Fiji
5 Jamaica
5 Fiji
6 Fiji
6 Jamaica
7 Jamaica
7 Fiji
8 Fiji
9 Fiji
8 Jamaica
DONE! Fiji
9 Jamaica
DONE! Jamaica

可以看到在輸出結果中兩個線程的名稱是混合在一起的,也沒有順序可循,這是因為這兩個線程是同時啟動並執行,並且是同時顯示輸出

 

2.執行Runnable介面的類實現run方法

通過建立一個實現了Runnable介面的對象,並以它作為線程的目標對象來建立一個線程。

Runnable介面:定義了一個抽象方法run()。定義如下:

public interface java.lang.Runnable{
public abstract void run();
}

建立的總體架構如下:

class MyRunner implements Runnable {
public void run() {

}
}

MyRunner r = new MyRunner();

Thread t = new Thread( ThreadGroup group, Runnable target, String name);

見例題:

ThreadTesterer.java
ThreadTest.java

例如:

public class Clock extends java.applet.Applet
implements Runnable {
Thread clockThread;
public void start() {
if (clockThread == null) {
clockThread = new Thread(this, "Clock");
clockThread.start();
}
}
public void run() {
while (clockThread != null) {
repaint();
try {
clockThread.sleep(1000);
} catch (InterruptedException e){
}
}
}
public void paint(Graphics g) {
Date now = new Date();
g.drawString(now.getHours() + ":"
+ now.getMinutes() + ":"
+ now.getSeconds(), 5, 10);
}
public void stop() {
clockThread.stop();
clockThread = null;
}
}

這是一個時鐘Applet,它顯示目前時間並逐秒進行更新。該Applet利用Runnable介面為其線程提供run()方法。類Clock由類Applet擴充而得,但同時它需要一個線程來實現時間的更新顯示。由於Java中不支援多重繼承,所以它不能再繼承類Thread,而是利用了Runnable介面。
首先,在start()方法中構造了一個名為clockThread的線程 並調用Thread.start()方法來啟動這一線程,即在Java運行時建立系統的線程關係。下面這句建立了一個新的線程:

clockThread = new Thread(this, "Clock");

其中this是Thread 構造方法中的第一個自變數,作為該線程的目標對象,它必須實現Runnable介面。在這種構造方法下,線程clockThread就以它的可啟動並執行目標對象中的run()方法為其run()方法,在本例中,這個目標對象就是Clock Applet。構造方法中的第二個變數為線程名。

線程被啟動以後,調用目標對象的run()方法,除非線程被停止。在run()方法的迴圈中,Applet重繪本身,然後睡眠1秒,同時要捕獲例外事件並進行處理。

如果你離開顯示時鐘的這一頁,應用程式將調用stop()方法,將線程置空。當你返回時,又會建立一個新的線程。

在具體應用中,採用哪種方法來構造線程體要視情況而定。通常,當一個線程已繼承了另一個類時,就應該用第二種方法來構造,即實現Runnable介面。

3.總結:

1.兩種方法均需執行線程的start方法為線程分配必須的系統資源、調度線程運行並執行線程的run方法。

2.在具體應用中,採用哪種方法來構造線程體要視情況而定。通常,當一個線程已繼承了另一個類時,就應該用第二種方法來構造,即實現Runnable介面。

3.線程的消亡不建議通過調用一個stop()命令。而是讓run()方法自然結束。

見例題: ThreadController.java

 

    

                                                       關閉

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.