Java并发----Callable、Future和FutureTask

Callable、Future和FutureTask

创建线程一般使用Thread或者实现Runnable接口,这种缺陷是执行完毕之后是无法获取到结果的。(run()返回是void)。
如果想获取到结果需要使用共享变量或者线程之间的通信获取,如此做不仅繁琐对编程能力有要求比较高。
从JAVA1.5提供了Callable、Future来使线程执行完毕之后返回结果。



下面是我总结的使用Callable、Future和FutureTask的使用方法:

1.Callable位于java.util.concurrent包,里面只声明了一个方法call();(类似run(),但是它是有返回结果类型的--V);
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}
一般配合ExecutorService类来使用,这个类中有submit方法:
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
一般情况下我们只使用第一个和第三个,第二个很少使用。
它们返回的都是Future,我们来看看这个是怎么使用的。

2.Future
Future就是对Callable和Runnable任务的执行结果进行取消、查询是否完成、获取结果等操作。必要时可通过get()获取结果,任务阻塞直到任务返回结果。

Future类位于java.util.concurrent包下:
public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
cancel方法用来取消任务,如果任务取消则返回成功true,否则返回fasle。-----mayInterruptIfRunning表示是否允许取消正在执行但没有执行完毕的任务,如果设置true,则表示允许取消。

isCancelled方法表示任务是否被取消成功。

isDone方法表示任务是否已经完成。

get方法表示用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回。

get(long timeout,TimeUnit unit)用来获取执行结果,如果在指定时间内未获取到则直接返回null。

此接口定义了许多对线程执行结果的一些验证和返回。具体实现类FutureTask才是核心。

3.FutureTask
FutureTask是Future接口的唯一实现类。
它实现了RunnableFuture接口,而这接口又继承了Runnable和Future接口。所以它可作为Runnable被线程执行,又可以作为Callable的返回值。


-------------------------------------------  使用案例  -------------------------------------------------

使用Callable和Future获取执行结果:
	List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
<span style="white-space:pre">		</span>Map<String, Object> params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果1");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果2");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果3");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果4");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果5");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果6");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果7");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果8");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果9");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果10");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果11");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果12");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果13");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果14");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果15");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果16");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果17");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果18");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果19");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>params = new HashMap<String, Object>();
<span style="white-space:pre">		</span>params.put("taskName", "结果20");
<span style="white-space:pre">		</span>list.add(params);
<span style="white-space:pre">		</span>Task<String> task = new SendTask();
<span style="white-space:pre">		</span>long start = System.currentTimeMillis();
<span style="white-space:pre">		</span>List<Future<String>> results = TaskHandler.dealTask(list, task,10000);
<span style="white-space:pre">		</span>long end = System.currentTimeMillis();
<span style="white-space:pre">		</span>System.out.println(end-start);
<span style="white-space:pre">		</span>int i=0;
<span style="white-space:pre">		</span>for (Future<String> f : results) {
<span style="white-space:pre">			</span>i++;
<span style="white-space:pre">			</span>System.out.println("返回结果:"+i);
<span style="white-space:pre">			</span>try {
<span style="white-space:pre">				</span>System.out.println(f.get());
<span style="white-space:pre">			</span>} catch (Exception e) {
<span style="white-space:pre">				</span>e.printStackTrace();
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}


public class SendTask implements Task<String>{
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>private Map<String, Object> params;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void taskParams(Map<String, Object> params) {
<span style="white-space:pre">		</span>this.params = params;
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public String call() throws Exception {
<span style="white-space:pre">		</span>System.out.println("线程等待2s");
<span style="white-space:pre">		</span>Thread.sleep(2000);
<span style="white-space:pre">		</span>System.out.println(params.get("taskName"));
<span style="white-space:pre">		</span>return "返回成功!";
<span style="white-space:pre">	</span>}


}

public static  <T>List<Future<T>> dealTask(List<Map<String, Object>> params,Task<T> task,long timeOut){
		List<Future<T>> list = new ArrayList<Future<T>>();
		//获取缓存线程池
		ExecutorService service = ThreadLocalHelper.getCachedPool();
		// 执行多任务,循环处理参数集
		Future<T> future = null;
		//初始化返回结果集
		for (Map<String, Object> param : params) {
			try {
				// 给任务设置任务参数
				task.taskParams(param);
				//执行任务
				future = service.submit(task);
				list.add(future);
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		//执行完毕后关闭线程池
		service.shutdown();
		//获取开始时间(若超过20S,则强制退出返回)
		long start = System.currentTimeMillis();
		long flag = 0;
		while(true){
			flag = System.currentTimeMillis()-start;
			if(service.isTerminated()||flag>=timeOut){
				System.out.println("线程执行完毕!");
				break;
			}
			try {
				Thread.sleep(10);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return list;
	}























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值