Callable与Future使用

Callable与Future应用

应用于异步的任务执行,类似JS的回调方法.

Future取得的结果类型与Callable返回的结果类型必须一致.

如异步执行方式:

public class FutureTaskDemo {

	public static void main(String[] args) {
		// 初始化一个Callable对象和FutureTask对象
		Callable<Object> pAccount = new PrivateAccount();
		FutureTask<Object> futureTask = new FutureTask<Object>(pAccount);
		// 使用FutureTask创建一个线程
		Thread pAccountThread = new Thread(futureTask);
		System.out.println("future task starts at " + System.nanoTime());
		
		pAccountThread.start();
		// 主线程执行自己的任务
		System.out.println("main thread doing something else here.");
		// 从其他帐户获取总金额
		int totalMoney = new Random().nextInt(100000);
		System.out.println(" You have " + totalMoney + " in your other Accounts. ");
		System.out.println(" Waiting for data from Private Account");
		// 测试后台的就计算线程是否完成,如果未完成,等待
		while(!futureTask.isDone()){
			try {
				Thread.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("future task ends at " + System.nanoTime());
		Integer privataAccountMoney = null;
		// 如果后台的FutureTask计算完成,则返回计算结果
		try {
			privataAccountMoney = (Integer) futureTask.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		System.out.println(" The total money you have is " + (totalMoney + privataAccountMoney.intValue()));
	}

}

// 创建一个Callable类,模拟计算一个私有帐户中的金额
class PrivateAccount implements Callable<Object> {
	
	Integer totalMoney;
	@Override
	public Integer call() throws Exception{
		Thread.sleep(5000);
		totalMoney = new Integer(new Random().nextInt(10000));
		System.out.println(" You have " + totalMoney + " in your private Account. ");
		return totalMoney;
	}
	
}

 采用ExecutorSevice的submit方法提交:

public class CallableAndFuture {

	public static void main(String[] args) {
		// Future(将来)取得的结果类型和Callable返回的结果类型必须一致.
		// Callable要采用ExecutorSevice的submit方法提交,返回的future对象可以取消任务.
		ExecutorService threadPool =  Executors.newSingleThreadExecutor();
		Future<String> future =	threadPool.submit(
				new Callable<String>() {
					public String call() throws Exception {
						Thread.sleep(2000);
						return "hello";
					};
				}
		);
		System.out.println("等待结果");
		try {
			// 一直等待结果
			System.out.println("拿到结果:" + future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		threadPool.shutdown();
		
		// CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务
		// 对应的Future对象,好比N块麦子,谁先成熟先收。
		ExecutorService threadPool2 =  Executors.newFixedThreadPool(10);
		CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
		for(int i=1;i<=10;i++){
			final int seq = i;
			completionService.submit(new Callable<Integer>() {
				@Override
				public Integer call() throws Exception {
					Thread.sleep(new Random().nextInt(5000));
					return seq;
				}
			});
		}
		for(int i=0;i<10;i++){
			try {
				// 先完成的先得到
				System.out.println(completionService.take().get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		
		threadPool2.shutdown();
	}
	
}