您的位置:首页 > 编程语言 > Java开发

Java并发编程(Callable、Future和CompletionService)

2015-09-04 18:11 609 查看
     上篇博客主要讲解了一下java并发编程中的线程池,这篇呢来谈一下,java并发编程中的任务管理。这篇博客主要涉及到的Future、CompletionService、callablerunnable接口






   runnable接口

   可以看看这个接口里面都有哪些操作
 
<span style="font-size:18px;"><span style="font-size:18px;">public interface Runnable {
public abstract void run();
}</span></span>


可以看到其中只有一个public void修饰的run()方法,注意返回值类似是void,调用这个方法是没有返回结果的。但有的时候需要返回结果,因此在java中还为我们提供了Callable这个接口
 
callable接口

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-family:Comic Sans MS;">public interface Callable<V> {
V call() throws Exception;
}</span></span></span>


这个方法,在runnable接口有了改进,首先有了返回值,其次有了异常的处理操作。

线程执行器操作Executor
java中可以,执行器Executor中可以提交两种任务,看下面的方法


<span style="font-size:18px;"><span style="font-size:18px;">public interface ExecutorService extends Executor {

void shutdown();

List<Runnable> shutdownNow();

boolean isShutdown();

boolean isTerminated();

boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;

<T> Future<T> submit(Callable<T> task);

<T> Future<T> submit(Runnable task, T result);

Future<?> submit(Runnable task);

}
</span></span>




有了上面这个线程池,来执行我们的任务,那么我们如何来获取我们想要达到的结果呢,java中为我们提供了Future接口

<span style="font-size:18px;"><span style="font-size:18px;">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;
}
</span></span>


 这个接口中一共列出来5个方法,其中get()方法用来获取执行的结果,其他几个方法用来判断整个的执行过程

下面来通过一个例子,深入的理解一下上面的几种关系

<span style="font-size:18px;"><span style="font-size:18px;">public static void main(String[] args) {
//创建一个线程执行器操作
ExecutorService threadPool = Executors.newSingleThreadExecutor();
//用Future来保存执行的结果
Future<String> future = threadPool.submit(
//线程执行器来执行任务
new Callable<String>() {
//任务来返回值
public String call() throws Exception {
Thread.sleep(2000);
return "hello";
};
});

System.out.println("等待结果");
try {
try {
//想要结果的时候,直接从Future中取出相应的结果就可以了
System.out.println("拿到结果"
+ future.get(100000, TimeUnit.SECONDS));
} catch (TimeoutException e) {
e.printStackTrace();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}

};</span></span>


 上面这个例子的流程如下

1.创建执行流程器对象:ExecutorService
2.创建任务对象Callable
3.执行流程器执行任务
4.把最终执行的任务结果保存到Futrue中
5.从Futrue中取出任务结果

CompleteService接口

这个接口是为了解决提交一组任务操作,具体方法如下

<span style="font-size:18px;"><span style="font-size:18px;">package java.util.concurrent;

public interface CompletionService<V> {

Future<V> submit(Callable<V> task);

Future<V> submit(Runnable task, V result);

Future<V> take() throws InterruptedException;

Future<V> poll();

Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
}
</span></span>


跟线程执行器类似,都是通过submit()方法来提交任务,然后通过take或者poll方法来获取保存任务的对象Future,最后通过Future的get方法来获取对象



<span style="font-size:18px;"><span style="font-size:18px;">public void test(){

//创建一个线程执行器对象
ExecutorService threadPool2 = Executors.newSingleThreadExecutor();

//创建执行一组任务的对象操作
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));
// TODO Auto-generated method stub
return seq;
}

});
}

for (int i = 0; i < 10; i++) {
try {
//来获取任务结果
System.out.println(completionService.poll().get());
} catch (Exception e) {
}
}

}</span></span>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: