业务中常常会有这样一种场景:多个资源需要同时处理,我们一般会采用以下几种方式
调用线程池的Task类继承Thread或者实现Runnable接口以达到多线程处理的目的;而这种方式却没有线程执行结果的返回值,这样的话往往有需要再做收集结果集,另外处理的方式。
另一种采用异步方式,描述为线程类继承Callable<V>的方式返回异步Future,这种方式会在每个线程返回V结果变量
首先了解Future使用方法:
package java.util.concurrent;
/**
* A <tt>Future</tt> represents the result of an asynchronous
* computation. Methods are provided to check if the computation is
* complete, to wait for its completion, and to retrieve the result of
* the computation. The result can only be retrieved using method
* <tt>get</tt> when the computation has completed, blocking if
* necessary until it is ready. Cancellation is performed by the
* <tt>cancel</tt> method. Additional methods are provided to
* determine if the task completed normally or was cancelled. Once a
* computation has completed, the computation cannot be cancelled.
* If you would like to use a <tt>Future</tt> for the sake
* of cancellability but not provide a usable result, you can
* declare types of the form {@code Future<?>} and
* return <tt>null</tt> as a result of the underlying task.
*
* <p>
* <b>Sample Usage</b> (Note that the following classes are all
* made-up.) <p>
* <pre> {@code
* interface ArchiveSearcher { String search(String target); }
* class App {
* ExecutorService executor = ...
* ArchiveSearcher searcher = ...
* void showSearch(final String target)
* throws InterruptedException {
* Future<String> future
* = executor.submit(new Callable<String>() {
* public String call() {
* return searcher.search(target);
* }});
* displayOtherThings(); // do other things while searching
* try {
* displayText(future.get()); // use future
* } catch (ExecutionException ex) { cleanup(); return; }
* }
* }}</pre>
*
* The {@link FutureTask} class is an implementation of <tt>Future</tt> that
* implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
* For example, the above construction with <tt>submit</tt> could be replaced by:
* <pre> {@code
* FutureTask<String> future =
* new FutureTask<String>(new Callable<String>() {
* public String call() {
* return searcher.search(target);
* }});
* executor.execute(future);}</pre>
*
* <p>Memory consistency effects: Actions taken by the asynchronous computation
* <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
* actions following the corresponding {@code Future.get()} in another thread.
*
* @see FutureTask
* @see Executor
* @since 1.5
* @author Doug Lea
* @param <V> The result type returned by this Future's <tt>get</tt> method
*/
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;
}
例如实例执行求多个资源业务操作之和
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* @Description:
* @ClassName: FutureTest
* @Author: zhubo
* @Date: 2016年9月28日 上午9:07:59
* <ModifyLog>
* @ModifyContent:
* @Author:
* @Date:
* </ModifyLog>
*/
public class FutureTest {
public static void main(String[] args) {
List<Resurce> list = new ArrayList<Resurce>();
for(int i =0;i<100;i++){
list.add(new Resurce(i+1,i+2));
}
System.out.println("end count:"+test2(list)+" date :"+new Date());
}
public static Integer test2(List<Resurce> list){
System.out.println("begin test2"+new Date());
List<Future<Integer>> workers;
ExecutorService executor = Executors.newFixedThreadPool(list.size());
workers = new ArrayList<Future<Integer>>(list.size());
final CountDownLatch latch = new CountDownLatch(list.size());
for(final Resurce resurce :list ){
workers.add(executor.submit(new Callable<Integer>() {
@Override
public Integer call() {
try {
//模拟业务操作
Thread.sleep(1000);
}catch(Exception e){
System.err.println("this has a Exception ");
e.printStackTrace();
}finally{
latch.countDown();
}
return resurce.add();
}
}));
}
try {
while (true) {
latch.await(10, TimeUnit.SECONDS);//一个较长的时间
if (latch.getCount() != list.size()) {
break;
}
}
} catch (InterruptedException e) {
System.err.println("this has a InterruptedException ");
e.printStackTrace();
}finally{
//线程池关闭用在此处是不合适的,应用中应该抽取close方法;此处仅为了测试
if(executor!=null){
executor.shutdown();
}
}
Integer count=0;
for (Future<Integer> worker : workers) {
try {
if (worker.isDone() && !worker.isCancelled()) {
Integer a = worker.get(1, TimeUnit.SECONDS);
count =count+a;
}
} catch (Exception e) {
System.err.println("this has a workerException ");
e.printStackTrace();
}
}
return count;
}
}