編寫多執行緒程式是為了實作多工的同步執行,從而能夠更好地提高執行速度。一般有三種方法,
Thread,Runnable,Callable.
Runnable和Callable的區別是,
(1)Callable規定的方法是call(),Runnable規定的方法是run().
(2)Callable在執行後可返回值,而Runnable在執行後不能返回值
(3)call方法可以拋出異常,run方法不可以
(4)執行Callable會返回Future物件,表示非同步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,並檢索計算的結果。通過Future物件可以瞭解執行情況,可取消執行,還可獲取執行結果。
- 通過實現Runnable介面來創建Thread執行緒:
步驟1:實作Runnable介面的類別:
步驟2:創建一個類物件:class SomeRunnable implements Runnable { public void run() { //do something here } }
Runnable oneRunnable = new SomeRunnable();
步驟3:由Runnable創建一個Thread物件:
步驟4:啟動執行緒:Thread oneThread = new Thread(oneRunnable);
至此,一個執行緒就創建完成了。oneThread.start();
注釋:執行緒的執行流程很簡單,當執行代碼oneThread.start();時,就會執行oneRunnable物件中的void run();方法,該方法執行完成後,執行緒就消亡了。 - 與方法1類似,通過實現Callable介面來創建Thread執行緒:其中,Callable介面(也只有一個方法)定義如下:
步驟1:創建實現Callable介面的類SomeCallable<Integer>(略);public interface Callable<V> { V call() throws Exception; }
步驟2:創建一個類物件:
步驟3:由Callable<Integer>創建一個FutureTask<Integer>物件:Callable<Integer> oneCallable = new SomeCallable<Integer>();
注:FutureTask<Integer>是一個包裝器,它通過接受Callable<Integer>來創建,它同時實現了Future和Runnable介面。FutureTask<Integer> oneTask = new FutureTask<Integer>(oneCallable);
步驟4:由FutureTask<Integer>創建一個Thread物件:
步驟5:啟動執行緒:Thread oneThread = new Thread(oneTask);
至此,一個執行緒就創建完成了。oneThread.start();
- 通過繼承Thread類來創建一個執行緒:
步驟1:定義一個繼承Thread類的子類:
步驟2:構造子類的一個物件:class SomeThead extends Thraad { public void run() { //do something here } }
SomeThread oneThread = new SomeThread();
步驟3:啟動執行緒:
至此,一個執行緒就創建完成了。oneThread.start();
注:這種創建執行緒的方法不夠好,主要是因為其涉及運行機制問題,影響程式性能。 - 通過執行緒pool來創建執行緒:
步驟1:創建執行緒pool:
步驟2:通過Runnable物件或Callable物件將任務提交給ExecutorService物件:ExecutorService pool = Executors.newCachedThreadPool();
注:Future是一個介面,它的定義如下:Future<Integer> submit(Callable<Integer> task);
至此,一個執行緒就創建完成了。public interface Future<T> { V get() throws ...; V get(long timeout, TimeUnit unit) throws ...; void cancle(boolean mayInterrupt); boolean isCancelled(); boolean isDone(); }
注:執行緒pool需叫用shutdown();方法來關閉。 - 通過事件分配執行緒直接使用程式中的原有執行緒:
使用方法:
直接叫用EventQueue類的靜態方法invokeLater():
注:叫用EventQueue.invokeLater(oneRunnable);會直接執行oneRunnable物件中的run()方法。EventQueue.invokeLater(oneRunnable);