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

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

     上篇博客主要讲解了一下java并发编程中的线程池,这篇呢来谈一下,java并发编程中的任务管理。这篇博客主要涉及到的FutureCompletionService、callablerunnable接口

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

   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>



版权声明:本文为博主原创文章,未经博主允许不得转载。