Java并发编程之线程管理(Executor框架13)

4.3运用执行器返回结果

Executor框架的优势之一就是你能够运行并发的任务并且获得对应的结果。Java 并发API完成这个功能是通过下面两个接口:

l  Callable: 这个接口有call()方法。在这个方法中,你不得不实现一个任务的逻辑代码。Callable接口是一个参数化的接口,意味着你不得不说明call()方法返回的数据类型。

l  Future:这个接口有一些方法去获取由Callable对象产生的结果和管理它的状态。

下面看一个例子,比较好的说明了如何使用Callable和Future类。

 

import java.util.ArrayList;
import java.util.List;
//import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

public class FactorialCalculator implements Callable<Integer> {
	/**
	 * Number to calculate the factorial
	 */
	private Integer number;
	
	public FactorialCalculator(){
	}
	/**
	 * Constructor of the class. Initializes the attributes
	 * @param number Number to calculate the factorial
	 */
	public FactorialCalculator(Integer number){
		this.number=number;
	}
	
	/**
	 * Method called by the executor to execute this task and calculate the factorial of a
	 * number
	 */
	@Override
	public Integer call() throws Exception {
		int num, result;
		
		num=number.intValue();
		result=1;
		
		// If the number is 0 or 1, return the 1 value
		if ((num==0)||(num==1)) {
			result=1;
		} else {
			// Else, calculate the factorial
			for (int i=2; i<=number; i++) {
				result *= i;
				Thread.sleep(20);
			}
		}
		System.out.printf("%s: %d\n",Thread.currentThread().getName(),result);
		// Return the value
		return result;
	}
	
	public void invokeCalling(){

		// Create a ThreadPoolExecutor with fixed size. It has a maximun of two threads
		ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(2);
		// List to store the Future objects that control the execution of  the task and
		// are used to obtain the results
		List<Future<Integer>> resultList=new ArrayList<Future<Integer>>();

		// Create a random number generator
//		Random random=new Random();
		// Create and send to the executor the ten tasks
		for (int i=0; i<10; i++){
			Integer number=new Integer(i);
			FactorialCalculator calculator=new FactorialCalculator(number);
			Future<Integer> result=executor.submit(calculator);
			resultList.add(result);
		}
		
		// Wait for the finalization of the ten tasks
		do {
			System.out.printf("Main: Number of Completed Tasks: %d\n"
					,executor.getCompletedTaskCount());
			int size = resultList.size();
			for (int i=0; i<size; i++) {
				Future<Integer> result=resultList.get(i);
				System.out.printf("Main: Task %d: %s\n", i, result.isDone());
			}
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (executor.getCompletedTaskCount()<resultList.size());
		
		// Write the results
		System.out.printf("Main: Results\n");
		for (int i=0; i<resultList.size(); i++) {
			Future<Integer> result=resultList.get(i);
			Integer number=null;
			try {
				number=result.get();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
			System.out.printf("Core: Task %d: %d\n",i,number);
		}
		
		// Shutdown the executor
		executor.shutdown();
	}
	
	public static void main(String []args){
		(new FactorialCalculator()).invokeCalling();
	}
}
    运行结果:

pool-1-thread-1: 1
Main: Number of Completed Tasks: 0
pool-1-thread-2: 1
Main: Task 0: true
Main: Task 1: true
Main: Task 2: false
Main: Task 3: false
Main: Task 4: false
Main: Task 5: false
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 2
pool-1-thread-2: 6
Main: Number of Completed Tasks: 4
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: false
Main: Task 5: false
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 24
Main: Number of Completed Tasks: 5
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: false
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-2: 120
Main: Number of Completed Tasks: 6
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 720
Main: Number of Completed Tasks: 7
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-2: 5040
Main: Number of Completed Tasks: 8
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: true
Main: Task 8: false
Main: Task 9: false
Main: Number of Completed Tasks: 8
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: true
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 40320
Main: Number of Completed Tasks: 9
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: true
Main: Task 8: true
Main: Task 9: false
pool-1-thread-2: 362880
Main: Results
Core: Task 0: 1
Core: Task 1: 1
Core: Task 2: 2
Core: Task 3: 6
Core: Task 4: 24
Core: Task 5: 120
Core: Task 6: 720
Core: Task 7: 5040
Core: Task 8: 40320
Core: Task 9: 362880

Java并发编程之线程管理(Executor框架13),布布扣,bubuko.com

Java并发编程之线程管理(Executor框架13)

上一篇:Java并发编程之线程管理(Executor框架15)


下一篇:Java并发编程之线程管理(Executor框架14)