Netty源码分析-ExecutorCompletionService

 

package java.util.concurrent;

public class ExecutorCompletionService<V> implements CompletionService<V> {
    //用来执行具体任务
    private final Executor executor;
    //用来封装Callable或Runnable对象
    private final AbstractExecutorService aes;
    //队列,用来存放已完成的任务
    private final BlockingQueue<Future<V>> completionQueue;


    //继承FutureTask,在发生done时把自己加入队列
    //done方法不管是任务正常完成,还是取消,或者异常都会调用
    private class QueueingFuture extends FutureTask<Void> {
        QueueingFuture(RunnableFuture<V> task) {
            super(task, null);
            this.task = task;
        }
        //重写done方法,在任务完成后加入到队列
        protected void done() { completionQueue.add(task); }
        private final Future<V> task;
    }

    //包装Callable
    private RunnableFuture<V> newTaskFor(Callable<V> task) {
        if (aes == null)
            return new FutureTask<V>(task);
        else
            return aes.newTaskFor(task);
    }

    //包装Runnable
    private RunnableFuture<V> newTaskFor(Runnable task, V result) {
        if (aes == null)
            return new FutureTask<V>(task, result);
        else
            return aes.newTaskFor(task, result);
    }

    //构造参数传入Executor
    public ExecutorCompletionService(Executor executor) {
        if (executor == null)
            throw new NullPointerException();
        this.executor = executor;

        //类型转换
        this.aes = (executor instanceof AbstractExecutorService) ?
            (AbstractExecutorService) executor : null;

        //链表队列
        this.completionQueue = new LinkedBlockingQueue<Future<V>>();
    }

     //构造参数传入Executor和队列
    public ExecutorCompletionService(Executor executor,
                                     BlockingQueue<Future<V>> completionQueue) {
        if (executor == null || completionQueue == null)
            throw new NullPointerException();
        this.executor = executor;
        this.aes = (executor instanceof AbstractExecutorService) ?
            (AbstractExecutorService) executor : null;
        this.completionQueue = completionQueue;
    }

    public Future<V> submit(Callable<V> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<V> f = newTaskFor(task);
        //提交一个任务,创建QueueingFuture进行封装,在任务状态切换后回调done方法,把自己加入队列
        executor.execute(new QueueingFuture(f));
        return f;
    }

    //提交一个任务,创建QueueingFuture进行封装,在任务状态切换后回调done方法,把自己加入队列
    public Future<V> submit(Runnable task, V result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<V> f = newTaskFor(task, result);
        executor.execute(new QueueingFuture(f));
        return f;
    }

    //获取并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则等待.
    public Future<V> take() throws InterruptedException {
        return completionQueue.take();
    }

    //获取已完成的任务并移除,如果不存在则返回null.
    public Future<V> poll() {
        return completionQueue.poll();
    }

    //获取已完成的任务并移除,如果不存在则等待,超时后返回null
    public Future<V> poll(long timeout, TimeUnit unit)
            throws InterruptedException {
        return completionQueue.poll(timeout, unit);
    }

}

 

等待所有任务完成的例子:

package com.ht.web.nio;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Demo {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<>(Executors.newFixedThreadPool(10));
		
		List<Callable<Integer>> list = new ArrayList<>();
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 1"); return 1;});
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 2"); return 2;});
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 3"); return 3;});
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 4"); return 4;});
		
		for (Callable<Integer> callable : list) {
			completionService.submit(callable);
		}
		
		for (int i = 0; i < list.size(); i++) {
			Future<Integer> future = completionService.take();
			System.out.println(future.isDone() + " + " + future.get());
		}
	}

}

只要有一个任务完成即可,结束其它任务:

package com.ht.web.nio;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Demo {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<>(Executors.newFixedThreadPool(10));
		
		List<Callable<Integer>> list = new ArrayList<>();
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 1"); return 1;});
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 2"); return 2;});
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 3"); return 3;});
		list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 4"); return 4;});
		
		
		List<Future<Integer>> futures = new ArrayList<Future<Integer>>();

		for (Callable<Integer> callable : list) {
			futures.add(completionService.submit(callable));
		}
		
		Integer result = null;
		
		try {
			for (int i = 0; i < list.size(); i++) {
				Future<Integer> future = completionService.take();
				if(future.get() != null) {
					result = future.get();
					break;
				}
			}
		} finally {
			for (int i = 0; i < futures.size(); i++) {
				futures.get(i).cancel(true);
			}
		}
		
		if(result != null) {
			System.out.println(result);
		}
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值