FutureTask——-Java中异步任务类的详细说明

直接看下面的实验,注释详细:



package com.tbc.java;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class FutureTaskAndExecutor {
   /**
    * 个人对FutureTask<T> 的理解: FutureTask<T>从字面上可以理解为:异步任务类。 FutureTask<T>好比一个Map,
    *  FutureTask<T> 中存放的是任务和该任务结束后返回的结果。可以理解为一个键值对(任务,任务的结果)
    *  当任务 加入到FutureTask的对象的时候  任务的结果此时为空,另外FutureTask的一个对象只能一次性添加一个任务。
    *  这个任务可以理解为实现Callable接口的类对象,要实现Callable接口的call方法,也就是说我们可以把我们要做的操作放在call方法里。
    *  FutureTask<T>中的泛型指的是   call方法的返回值的实际类型即  return sum中sum 的类型。
    *  FutureTask中有个get()方法,当调用该方法时,获取到的值是 call方法中返回的值,
    *  get()方法只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常。 
    *  
    *  
    *  自己的疑问:我在下面做了一个实验,做了一个for循环验证了get()方法确实是阻塞的,既然是一直阻塞的,那么将get放在主线程中调用,不会出现问题吗?
    *  这个get到底如何调用才是比较好的方法呢?本人尚未理解透彻,若有不通见解,请留言评论。
    */
    /**
     * 本例子中加入了线程池的操作,将异步任务加入到线程池,将一些耗时的操作放入线程中操作,主线程还可以做些别的事情
     */
	public static void main(String[] args) {
		List<FutureTask<Integer>> list =new ArrayList<FutureTask<Integer>>();
		/**
		 * 创建线程池,线程池的大小和List.size没有啥必然的关系,一般的原则是<=list.size,多出来浪费不好
		 */
		ExecutorService exec = Executors.newFixedThreadPool(5);  //创建线程池,线程个数为5个
		for(int i =0; i <10; i++) {
			/**
			 * 创建对象 
			 */
			FutureTask<Integer> ft =new FutureTask<Integer>(new GetSum(i));
			/**
			 * 添加到list,方便后面取得结果
			 */
			list.add(ft);
			/**
			 *  一个个提交给线程池,当然也可以一次性的提交给线程池,exec.invokeAll(list);
			 */
			exec.submit(ft);
		}
		// 开始统计结果
		Integer total = 0;
		for(FutureTask<Integer> ft : list)
		{
				try 
				{
					System.out.println("在get执行前,total:-----》"+total);
					System.out.println("在get执行前,时间:-----》"+new Date());				
					total = total + ft.get();
					System.out.println("在get执行后,total:------》"+total);
					System.out.println("在get执行后,时间:------》"+new Date());
			
				} catch (InterruptedException e) {			
					e.printStackTrace();
				} catch (ExecutionException e) {			
					e.printStackTrace();
				}
			
		}

		// 处理完毕,一定要记住关闭线程池,这个不能在统计之前关闭,因为如果线程多的话,执行中的可能被打断
		exec.shutdown();
		System.out.println("多线程计算后的总结果是:" + total);

	}
}
class GetSum implements Callable {
	private Integer total;
	private Integer sum = 0;

	public GetSum(Integer total)
	{
		this.total = total;
	}
	public Object call() throws Exception 
	{
		sum=total+1;
		System.out.println(Thread.currentThread().getName() + " sum:" + sum);
		for (int i = 0; i < 1500000000L; i++) {
			
		}
		return sum;
	}

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值