天天看點

以Android環境為例的多線程學習筆記(四)----------Callable與Future

在JAVA的多線程機制中,Runnable接口可以用來封裝一個異步運作的任務,但是它相當于是一個沒有參數類型和傳回

值的異步方法,是以在JAVA中就又出現了callable機制,callable是一個參數化的類型接口,裡面隻有一個call方法,但是該方法是

有傳回值的,而且傳回值類型就是參數類型。與callable接口相配套使用的就是Future接口,其作用就是用來儲存異步運算的結果和

和啟動一個異步運算,Future接口中一共有五個方法,分别用來查詢和控制線程運作的狀态和結構。

Future接口中的方法清單:

public interface Future<V>
	{
		V get() throws ....;//用來傳回運算的最後結果,如果計算還未完成,則會被阻塞
		/*
		 *如果計算完成,則傳回true
		 *如果計算完成之前,調用這個方法逾時,則會發生TimeoutException異常。
		 *如果運作時線程被中斷則會發生InterruptedException中斷異常
		 *否則被阻塞
		 */
		V get(long timeout,TimeUnit unit) throws...;
		/*
		 * 取消運算,mayInterrupt為true時中斷線程,但此時如果線程已經被阻塞或者休眠則會發生InterruptedException中斷異常
		 */
		void cancle(boolean mayInterrupt);
		boolean isCancleed();//判斷線程是否被取消
		boolean isDone();//判斷計算是否已經完成
	}
           

但是在實際的運用中間我們還有更簡潔的機制那就是FutureTask包裝器,它可将Callable轉換成Future和Runnable,它同時是實作了兩者的接口的。

具體的使用方法如下面的代碼:

/** 
     * 定義一個任務類,實作Callable接口  
     */  
    public static class MyCallableClass implements Callable<String>{   
      
        private int value = 0;   
        public MyCallableClass(int flag){   
            this.value = flag;   
        }   
        public String call() throws Exception{   
            if (this.value == 0){
                // 如果value的值為0,則立即傳回   
                return "value = 0";   
            }    
            } else {   
                // value不為0,則抛出異常   
                throw new Exception("Invalid value!");   
            }   
        }   
    }   
           

//開啟線程

case R.id.button3:

			MyCallableClass task1 = new MyCallableClass(0);   
		        FutureTask<String> Futask = new FutureTask<String>(task1);
		        Thread t = new Thread(Futask);
		        t.start();
		        try{
		        System.out.println("task1: " + Futask.get()); 
		        }
		        catch(Exception e)
		        {
		            
		            System.out.println(e.toString());   
		        }
			
			break;

           

線程結束後,最後的結果将會輸出“alue=0”。這樣也就簡單的實作了将一個線程裡運算結果最後傳回的效果,其實這個功能說更簡單一點也就是利用Future

的特性實作了在主線程和子線程的通信問題,在主線程中可以得到子線程的最後結果,和控制、判斷子線程的運作狀态,不過這種通信效果僅僅隻是單向的,并不完美。

如果要實作線程間的完美通信,那就要用到一個更複雜的線程間的通信機制了,嗯,等下幾次再詳細的寫這個線程通信問題吧。