一. 實現(xiàn) Runnable 接口,并實現(xiàn)該接口的 run() 方法。
主要步驟:
- 自定義類并實現(xiàn) Runnable 接口,實現(xiàn) run() 方法。
- 創(chuàng)建 Thread 對象,用實現(xiàn) Runnable 接口的對象作為參數(shù)實例化該 Thread 對象。
- 調(diào)用 Thread 的 start 方法。
class MyThread implements Runnable {
// create my own Thread class
public void run() {
System.out.println("Thread body");
}
}
public class Test {
public static void main(String[] args) {
MyThread thread = new MyThread();
Thread t = new Thread(thread);
t.start(); //start the thread
}
}
二. 繼承 Thread 類,重寫 run 方法。
Thread是實現(xiàn)了 Runnable 接口的一個實例,它代表了一個線程的實例,并且啟動線程的唯一方法就是通過 Thread 類的 start()方法。start()方法是一個 native(本地)方法,它將啟動一個新線程,并執(zhí)行 run()方法(Thread 中提供的 run()方法是一個空方法)。注意,當 start()方法調(diào)用后并不是立即執(zhí)行多線程代碼,而是使該線程變?yōu)榭蛇\行態(tài)(Runnable),什么時候運行多線程代碼是由操作系統(tǒng)決定的。
class MyThreadB extends Thread {
public void run() {
System.out.println("Thread body");
}
}
public class Test {
public static void main(String[] args) {
MyThreadB thread = new MyThreadB();
thread.start();
}
}
三. 實現(xiàn) Callable接口,重寫 call()方法。
。
Callable 對象實際屬于 Executor 框架中的功能類,Callable 接口與 Runnable 接口類似,但提供了更強大的功能,包括以下三點:**
- Callable 可以在任務結束后提供一個返回值,Runnable無法提供此功能。
- Callable中的 call()方法可以拋出異常,而 Runnable的 run()方法不能拋異常。
- 運行 Callable 可以拿到一個 Future 對象,F(xiàn)uture 對象表示異步計算的結果。它提供了檢查計算是否完成的方法。由于線程屬于異步計算模型,所以無法從其他線程中得到方法的返回值,在這種情況下,就可以使用 Future 來監(jiān)視目標線程調(diào)用 call()方法的情況,當調(diào)用 Future 的 get()方法以獲取結果時,當前線程就會阻塞,直到 call()方法結束返回結果。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Created by qd on 12/5/17.
*/
public class CallableAndFuture {
public static class CallableTest implements Callable<String> {
public String call() throws Exception {
return "Hello World!";
}
}
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<String> future = threadPool.submit(new CallableTest());
try {
System.out.println("waiting thread to finish");
System.out.println(future.get()); //等待線程結束,并獲取返回結果
} catch (Exception e) {
e.printStackTrace();
}
}
}
當需要實現(xiàn)多線程的時候,一般推薦實現(xiàn) Runnable 接口的方式,原因如下:首先,Thread 類定義了多種方法可以被派生類使用或重寫,但是只有 run 方法是必須被重寫的,在 run 方法中實現(xiàn)這個線程的主要功能。這當然是實現(xiàn) Runnable 接口所需的同樣的方法。而且,很多 java 開發(fā)人員認為,一個 類僅在它們需要被加強或被修改時才會被繼承。因此,如果沒有必要重新 Thread 類的其他方法,那么通過繼承 Thread 的實現(xiàn)方式與實現(xiàn) Runnable 接口的效果相同,在這種情況下最好通過實現(xiàn) Runnable 接口的方式來創(chuàng)建線程。