1. 程式人生 > >java 多執行緒之future用法和意義

java 多執行緒之future用法和意義

在併發程式設計時,一般使用runnable,然後扔給執行緒池完事,這種情況下不需要執行緒的結果。所以run的返回值是void型別。

如果是一個多執行緒協作程式,比如菲波拉切數列,1,1,2,3,5,8...使用多執行緒來計算。但後者需要前者的結果,就需要用callable介面了。

callable用法和runnable一樣,只不過呼叫的是call方法,該方法有一個泛型返回值型別,你可以任意指定。

執行緒是屬於非同步計算模型,所以你不可能直接從別的執行緒中得到函式返回值。 

這時候,Future就出場了。Futrue可以監視目標執行緒呼叫call的情況,當你呼叫Future的get()方法以獲得結果時,當前執行緒就開始

阻塞,直接call方法結束返回結果。

從下面三段程式碼可以看出

runnable介面實現的沒有返回值的併發程式設計。

package test;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class futureTest {
	
    public static class Task implements Runnable{
    	
    	public void run(){
    		System.out.println("ah");
    	}
    }
    
    
	public static void main(String[] args) {
		//建立執行緒池,無固定長度的執行緒池
		ExecutorService es=Executors.newCachedThreadPool();
		for (int i = 0; i < 100; i++) {
			es.submit(new Task());
			}

	}

}
callable實現的存在返回值的併發程式設計。(call的返回值String受泛型的影響)
package test;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import test.futureTest.Task;

public class CallableTest {
	public static class Task implements Callable{ //實現callable介面,是有返回值的call方法,而runnable介面的run方法是沒有返回值
    	
		@Override
		public String call() throws Exception {
			System.out.println("ah");
			return "hello ah!";
		}
    }	
	public static void main(String[] args) {
		//建立執行緒池,無固定長度的執行緒池
		ExecutorService es=Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			es.submit(new Task());
		}
	}

}

使用callable介面,使用Future來接收call方法返回的結果,
public static class Task implements Callable<String>{ //實現callable介面,是有返回值的call方法,而runnable介面的run方法是沒有返回值
    	
		@Override
		public String call() throws Exception {
			System.out.println("ah");
			return "hello ah!";
		}
    }
	
	public static void main(String []args) throws InterruptedException, ExecutionException{
		List<Future<String>> result = new ArrayList<Future<String>>(); //使用泛型來建立一個list佇列,泛型型別是Future<String>
		ExecutorService es=Executors.newCachedThreadPool();
		
		for (int i = 0; i < 10; i++) {
			result.add(es.submit(new Task())); //把返回的結果放入list集合中
		}
		
		//遍歷list集合,獲取future
		for (Future<String> future : result) {
			 System.out.println(future.get()); //使用future的get方法來獲取call方法返回的結果
		}
		
	}

這樣就可以輸出hello ah!