Callable和Future


Callable和Future

概述
  • Callable和Future,它倆很有意思的,一個產生結果,一個拿到結果。

  • Future表示一個可能還沒有完成的異步任務的結果,針對這個結果可以添加Callback以便在任務執行成功或失敗后作出相應的操作。

  • Callable接口中只有一個call()方法,和Runnable相比,該方法有返回值並允許拋出異常

  • FutureTask是Runnable, Future接口的實現類。

  • RunnableFuture

    • 這個接口同時繼承Future接口和Runnable接口,在成功執行run()方法后,可以通過Future訪問執行結果。這個接口都實現類是FutureTask,一個可取消的異步計算,這個類提供了Future的基本實現,后面我們的demo也是用這個類實現,它實現了啟動和取消一個計算,查詢這個計算是否已完成,恢復計算結果。計算的結果只能在計算已經完成的情況下恢復。如果計算沒有完成,get方法會阻塞,一旦計算完成,這個計算將不能被重啟和取消,除非調用runAndReset方法。
    • FutureTask能用來包裝一個Callable或Runnable對象,因為它實現了Runnable接口,而且它能被傳遞到Executor進行執行。為了提供單例類,這個類在創建自定義的工作類時提供了protected構造函數。
  • enter image description here

Future的主要方法
  • get()方法可以當任務結束后返回一個結果,如果調用時,工作還沒有結束,則會阻塞線程,直到任務執行完畢get(long timeout,TimeUnit unit)做多等待timeout的時間就會返回結果
  • cancel(boolean mayInterruptIfRunning)方法可以用來停止一個任務,如果任務可以停止(通過mayInterruptIfRunning來進行判斷),則可以返回true,如果任務已經完成或者已經停止,或者這個任務無法停止,則會返回false.
  • isDone()方法判斷當前方法是否完成
  • isCancel()方法判斷當前方法是否取消
示例
  • 普通線程模式
public class BumThread extends Thread{
	
	@Override
	public void run() {
		try {
			Thread.sleep(1000*3);
			System.out.println("包子准備完畢");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
 
}

public class ColdDishThread extends Thread{
	
	@Override
	public void run() {
		try {
			Thread.sleep(1000);
			System.out.println("涼菜准備完畢");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
 
}

public static void main(String[] args) throws InterruptedException {
		long start = System.currentTimeMillis();
		
		// 等涼菜 -- 必須要等待返回的結果,所以要調用join方法
		Thread t1 = new ColdDishThread();
		t1.start();
		t1.join();
		
		// 等包子 -- 必須要等待返回的結果,所以要調用join方法
		Thread t2 = new BumThread();
		t2.start();
		t2.join();
		
		long end = System.currentTimeMillis();
		System.out.println("准備完畢時間:"+(end-start));
}

  • Future模式
public static void main(String[] args) throws InterruptedException, ExecutionException {
		long start = System.currentTimeMillis();
		
		// 等涼菜 
		Callable ca1 = new Callable(){
 
			@Override
			public String call() throws Exception {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return "涼菜准備完畢";
			}
		};
		FutureTask<String> ft1 = new FutureTask<String>(ca1);
		new Thread(ft1).start();
		
		// 等包子 -- 必須要等待返回的結果,所以要調用join方法
		Callable ca2 = new Callable(){
 
				@Override
				public Object call() throws Exception {
					try {
						Thread.sleep(1000*3);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					return "包子准備完畢";
			}
		};
		FutureTask<String> ft2 = new FutureTask<String>(ca2);
		new Thread(ft2).start();
		
		System.out.println(ft1.get());
		System.out.println(ft2.get());
		
		long end = System.currentTimeMillis();
		System.out.println("准備完畢時間:"+(end-start));
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM