• Java_并发线程_CompletionService


    1.CompletionService源代码分析

    CompletionService内部实现还是维护了一个可堵塞的队列,通过代理设计模式。从而操作队列。
        /**
         * Creates an ExecutorCompletionService using the supplied
         * executor for base task execution and a
         * {@link LinkedBlockingQueue} as a completion queue.
         *
         * @param executor the executor to use
         * @throws NullPointerException if executor is {@code null}
         */
        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>>(); //新建一个完毕队列 }

    	//通过submit提交Callable任务对象
        public Future<V> submit(Callable<V> task) {
            if (task == null) throw new NullPointerException();
            RunnableFuture<V> f = newTaskFor(task);
            executor.execute(new QueueingFuture(f));//线程池运行task对象
            return f;
        }
        /**
         * FutureTask extension to enqueue upon completion
         */
        private class QueueingFuture extends FutureTask<Void> {
            QueueingFuture(RunnableFuture<V> task) {
                super(task, null);
                this.task = task;
            }
            protected void done() { 
            	completionQueue.add(task); //运行玩后将task返回对象放置于完毕队列
            }
            private final Future<V> task;
        }
    	//通过take方法取得Future对象
        public Future<V> take() throws InterruptedException {
            return completionQueue.take();
        }


    2.实例

    	public static void main(String[] args) {
    
    		ExecutorService threadPool = Executors.newFixedThreadPool(3);
    		
    		CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool);
    		//将任务加入至threadPool池中。可是仅仅分配3个Thread对象
    		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));
    					return seq;
    				}
    			});
    		}
    		
    		
    		for (int i = 0; i < 10; i++) {
    			try {
    				//completionService.take(), 至于call方法运行完毕,take堵塞採用数据
    				//future.get() 堵塞, 仅仅有当call运行完毕,
    				System.out.println(completionService.take().get());
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			} catch (ExecutionException e) {
    				e.printStackTrace();
    			}
    		}
    	}

  • 相关阅读:
    升级windows 11小工具
    windows 10更新升级方法
    您需要了解的有关 Oracle 数据库修补的所有信息
    Step by Step Apply Rolling PSU Patch In Oracle Database 12c RAC Environment
    Upgrade Oracle Database Manually from 12.2.0.1 to 19c
    如何应用版本更新 12.2.0.1.210420(补丁 32507738 – 2021 年 4 月 RU)
    xtrabackup 安装、备份和恢复
    Centos_Lvm expand capacity without restarting CentOS
    Centos_Lvm_Create pv vg lv and mount
    通过全备+relaylog同步恢复被drop的库或表
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5145206.html
Copyright © 2020-2023  润新知