1. 程式人生 > >java執行緒中Callble和Future的使用

java執行緒中Callble和Future的使用

     Callable是java.util.concurrent包中一個介面,Callable 介面類似於Runnable,兩者都是為那些其例項可能被另一個執行緒執行的類設計的。但是Runnable 不會返回結果,並且無法丟擲經過檢查的異常。此介面中就聲明瞭一個方法call(),這個方法計算結果,如果無法計算結果,則丟擲一個異常。Executors 類包含一些從其他普通形式轉換成 Callable 類的實用方法。我們來看看此介面和它方法宣告的原始碼(JDK1.6):

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}
   Future也是java.util.concurrent包中一個介面,Future介面 表示非同步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,並獲取計算的結果。計算完成後只能使用get()或者get(long timeout,TimeUnit unit) 方法來獲取結果,如有必要,計算完成前可以阻塞此方法。取消則由cancel(boolean mayInterruptIfRunning) 方法來執行。還提供了其他方法,以確定任務是正常完成還是被取消了。一旦計算完成,就不能再取消計算。如果為了可取消性而使用Future 但又不提供可用的結果,則可以宣告Future<?>
形式型別、並返回null
作為底層任務的結果, FutureTask 類是Future 的一個實現。我們來看看原始碼(JDK1.6):
public interface Future<V> {

    /**
     * Attempts to cancel execution of this task.  This attempt will
     * fail if the task has already completed, already been cancelled,
     * or could not be cancelled for some other reason. If successful,
     * and this task has not started when <tt>cancel</tt> is called,
     * this task should never run.  If the task has already started,
     * then the <tt>mayInterruptIfRunning</tt> parameter determines
     * whether the thread executing this task should be interrupted in
     * an attempt to stop the task.
     *
     * <p>After this method returns, subsequent calls to {@link #isDone} will
     * always return <tt>true</tt>.  Subsequent calls to {@link #isCancelled}
     * will always return <tt>true</tt> if this method returned <tt>true</tt>.
     *
     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
     * task should be interrupted; otherwise, in-progress tasks are allowed
     * to complete
     * @return <tt>false</tt> if the task could not be cancelled,
     * typically because it has already completed normally;
     * <tt>true</tt> otherwise
     */
    boolean cancel(boolean mayInterruptIfRunning);

    /**
     * Returns <tt>true</tt> if this task was cancelled before it completed
     * normally.
     *
     * @return <tt>true</tt> if this task was cancelled before it completed
     */
    boolean isCancelled();

    /**
     * Returns <tt>true</tt> if this task completed.
     *
     * Completion may be due to normal termination, an exception, or
     * cancellation -- in all of these cases, this method will return
     * <tt>true</tt>.
     *
     * @return <tt>true</tt> if this task completed
     */
    boolean isDone();

    /**
     * Waits if necessary for the computation to complete, and then
     * retrieves its result.
     *
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     */
    V get() throws InterruptedException, ExecutionException;

    /**
     * Waits if necessary for at most the given time for the computation
     * to complete, and then retrieves its result, if available.
     *
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     * @throws TimeoutException if the wait timed out
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

   下邊我們就通過一個例子來簡單瞭解它們是如何使用的。
package CallableFuture;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CallableFutureTest {

    public static void main(String[] args) {

    	 // 定義3個Callable型別的任務
    	Callable task0 = new CallableTest(0);
    	Callable task1 = new CallableTest(1);
    	Callable task2 = new CallableTest(2);
        
        ExecutorService es = Executors.newFixedThreadPool(3);	// 建立一個執行任務的執行緒池
        try {
            
            Future future0 = es.submit(task0);	// 提交併執行任務1,任務啟動時返回了一個Future物件
            System.out.println("task0執行結果 :" + future0.get());	// 獲得第一個任務的結果,如果呼叫get方法直到當前執行緒會等待任務執行完畢後才往下執行
            
            Future future1 = es.submit(task1);	// 提交併執行任務2,任務啟動時返回了一個Future物件
            String result1=null;
            try{
            	result1=(String) future1.get(6,TimeUnit.SECONDS);	// 如有必要,最多等待6秒之後,獲取其結果(如果結果可用),因為此時任務在無限迴圈肯定超時
            }catch(TimeoutException e){
            	System.out.println("future1用get獲取超時了!此時任務1的執行結果:"+result1);
            }

            Future future2 = es.submit(task2);	// 提交併執行任務2,任務啟動時返回了一個Future物件
            System.out.println("任務2開始執行了.....");
            Thread.sleep(2000);		//主執行緒即當前執行緒停止2秒往下執行
            System.out.println("task1被cancel()取消任務,結果: " + future1.cancel(true));	//中斷任務1的迴圈
            System.out.println("task2執行結果:" + future2.get());
        } catch (Exception e){
            System.out.println(e.toString());
        }

       // 停止任務執行服務
        es.shutdownNow();
        System.out.println("所有任務全部結束了!");
    }
}
class CallableTest implements Callable{
	
    public int testData = 0; 

    public CallableTest(int testData){
        this.testData = testData;
    }
    
    @Override
    public String call() throws Exception{
	  	if (this.testData == 0){  
	  		return "testData = 0";
	  	} 
	    if (this.testData == 1){  
	    	try {
	    		while (true) {
	    			System.out.println("任務1執行中.....");
	                Thread.sleep(1000);
	            }
	        } catch (InterruptedException e) {
	      	    System.out.println("任務1中斷了.....");
	        }
	        return "如果被cancle,則不會接受返回值!";
	   } else {
		    Thread.sleep(10000);
		    return "任務2睡了10秒!";
	   }
   }
}

執行結果如下:
task0執行結果 :testData = 0
任務1執行中.....
任務1執行中.....
任務1執行中.....
任務1執行中.....
任務1執行中.....
任務1執行中.....
future1用get獲取超時了!此時任務1的執行結果:null
任務2開始執行了.....
任務1執行中.....
任務1執行中.....
task1被cancel()取消任務,結果: true
任務1中斷了.....
task2執行結果:任務2睡了10秒!
所有任務全部結束了!

    最後,認真看過的網友們,大神們,如有感覺我這個程式猿有哪個地方說的不對或者不妥或者你有很好的

議或者建議或點子方法,還望您大恩大德施捨n秒的時間留下你的寶貴文字(留言),以便你,我,還有廣大的程式猿們更快地成長與進步.......




相關推薦

java執行CallbleFuture的使用

     Callable是java.util.concurrent包中一個介面,Callable 介面類似於Runnable,兩者都是為那些其例項可能被另一個執行緒執行的類設計的。但是Runnable 不會返回結果,並且無法丟擲經過檢查的異常。此介面中就聲明瞭一個方法c

java執行yield()join()的區別

package test.core.threads; public class JoinExample { public static void main(String[] args) throws InterruptedException { Thread t = new Thr

Java執行】CallableFuture

Future模式 Future介面是Java執行緒Future模式的實現,可以來進行非同步計算。 Future模式可以這樣來描述: 我有一個任務,提交給了Future,Future替我完成這個任務。期間我自己可以去做任何想做的事情。一段時間之後,我就便可以從Future那兒

java 執行的 wait()sleep()

wait() 方法是寫在java.lang.Object類中的 (ps: notify()  notifyAll()也是在Object中定義的) wait()原始碼註釋: Causes the current thread to wait until either a

java執行學習(一): 多執行start()run()的區別

趁著有空,看看執行緒Thread的原始碼,挺有意思的 這裡來說說多執行緒中start()和run()的區別。 1-跟start()有關的原始碼: public class Thread implements Runnable { private ThreadGroup group;

Java執行知識-CallableFuture

Callable和Future出現的原因 建立執行緒的2種方式,一種是直接繼承Thread,另外一種就是實現Runnable介面。 這2種方式都有一個缺陷就是:在執行完任務之後無法獲取執行結果。 如果需要獲取執行結果,就必須通過共享變數或者使用執行緒通訊的方式來達到效果,這樣使用起來就比

Java執行之CallableFuture介面的實現

Callable和Future     Callable介面定義了一個call方法可以作為執行緒的執行體,但call方法比run方法更強大:     A、call方法可以有返回值     B、call方法可以申明丟擲異常       Callable介面是JDK5後

JAVA執行的關於waitnotify不錯的例子

JAVA執行緒中的關於wait和notify不錯的例子,原來的實現方法:   public class ListAdd1 { private volatile static List list = new ArrayList(); public void add(){

Java執行start()run()的區別

Java的執行緒是通過java.lang.Thread類來實現的。VM啟動時會有一個由主方法所定義的執行緒。可以通過建立Thread的例項來建立新的執行緒。每個執行緒都是通過某個特定Thread物件所對應的方法run()來完成其操作的,方法run()稱為執行緒體。通過呼叫Thread類的start(

Java執行sleep()、wait()notify()notifyAll()、yield()、join()等方法的用法區別

Java執行緒中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和區別從作業系統的角度講,os會維護一個ready queue(就緒的執行緒佇列)。並且在某一

Java執行的joinyield

public class TestJoin { public static void main(String[] args) { MyThread2 t1 = new MyThread2(

Java執行 synchronizedLock的區別

我們已經瞭解了Java多執行緒程式設計中常用的關鍵字synchronized,以及與之相關的物件鎖機制。這一節中,讓我們一起來認識JDK 5中新引入的併發框架中的鎖機制。 我想很多購買了《Java程式設計師面試寶典》之類圖書的朋友一定對下面這個面試題感到非常熟悉: 問:請對比synchronized與java

執行學習---CallableFuture的使用(十)

1.Callable和Future適用於帶有返回結果的多執行緒 示例 public class CallAndFutureStudy { public static void main(String[] args) { ExecutorService threadPool

python執行joinsetDaemon

join([timeout]) 主執行緒A中,建立子執行緒B,B呼叫join函式會使得主執行緒阻塞,直到子執行緒執行結束或超時。引數timeout是一個數值型別,用來表示超時時間,如果未提供該引數,那麼主調執行緒將一直阻塞直到子執行緒結束。 注意:必須在start() 方法呼叫之後設

Java執行之semaphoreExchanger

Semaphore是Java執行緒的一個計數訊號量。我們可用於多執行緒的併發訪問控制。 就像我們常見的執行緒池,資料庫連線池就可以使用Semaphore進行邏輯的實現。Semaphore中我們就介紹兩個最常用的兩個方法。 acquire() 從Semaphore獲取許可,如果計數不小於0

Java執行阻塞佇列

Java語言提供了java.util.concurrent包解決執行緒同步問題,concurrent包中的阻塞佇列BlockingQueue能夠很好地執行緒同步問題, 介面BlockingQueue提供如下幾個執行緒同步方法 儲存資料:   offer(obj):向佇列BlockingQue

執行佇列同/非同步執行問題

佇列分為並行佇列和序列佇列,執行方式分為同步執行和非同步執行,那麼組合一下就有四種方式,下面我會用GCD來驗證和總結一下各個組合的特性。 併發佇列,同步執行 //併發佇列+同步執行 //不會開啟新執行緒,任務順序執行 -(void)test1{ NSLog(@"併發佇列+

JVM學習之java執行實現&排程狀態轉換

1 謹慎使用java 多執行緒   如何提升效率:      使用java時推薦利用多執行緒處理一些操作絕大多數情況下確實能提高效率,提高效率的原理在哪裡呢,為什麼說絕大多說情況呢。        在CPU單核時代,我們知道某一時刻工作的執行緒只能是一條,那多執行緒為什

java執行池ThreadPoolExecutor阻塞佇列BlockingQueue,Executor, ExecutorService

ThreadPoolExecutor 引數最全的建構函式 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,

執行waitsleep區別

wiat和sleep的區別? 1、wait可以指定時間也可以不指定      sleep必須指定時間。 2、在同步中,對cpu的執行權和鎖的處理不同 wait:釋 放執行權,釋放鎖。 slee