AbstractExecutorService任务提交<一>

      现在可以来记录AbstractExecutorService的异步任务提交了,单刀直入吧,先看三个submit方法提交单个任务:

 

public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Object> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

 

     有了上一篇铺垫很好理解,首先将RunnableCallable任务包装成RunnableFuture ftask,然后就交给execute(ftask)方法,接着就马上返回ftask。这个execute(Runnable)方法将在子类ThreadPoolExecutor中实现,这里先不着急,看下这个Executor接口中对该方法的描述: 

/
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the <tt>Executor</tt> implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution.
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);

  

      在将来某个时刻执行给定的任务command,说明这个方法是将来会去执行,在主线程(submit方法)中是不会阻塞的。另外,注意到如果提交的是Runnable接口,返回的future对象中其结果是在任务提交时候就指定了的,要么是null,要么是T result。上面的分析可以简单测试下: 

 

//Callable 任务
class CallabelTask implements Callable<String>{
		String name;
		public CallabelTask(String name){
			this.name = name;
		}
		@Override
		public String call() throws Exception {
			System.out.println("Start to execute the task " + name);
			TimeUnit.SECONDS.sleep(5);
			return name + " is done!";
		}
		
	}

 

   //测试提交 Callable 任务

public static void submitCallableTask()throws Exception{
		ExecutorService executor = Executors.newCachedThreadPool();
		List<Future<String>> results = new ArrayList<Future<String>>(5);
		for(int i = 0; i < 5; ){
			results.add(executor.submit(new CallabelTask("task_"+(++i))));
		}
		System.out.println("All the tasks have been submited through invokeAll method!");
		executor.shutdown();
		for(Future<String> f : results)
			System.out.println(f.get());
	}

 

        submitCallableTask() 调用结果: 

 

 public static void main(String[] args) throws Exception { submitCallableTask();
}
//调用submitCallableTask的结果:
All the tasks have been submited through invokeAll method!
Start to execute the task task_1
Start to execute the task task_5
Start to execute the task task_3
Start to execute the task task_4
Start to execute the task task_2
task_1 is done!
task_2 is done!
task_3 is done!
task_4 is done!
task_5 is done!

 

        从返回的结果看,主线程在执行完executor.submit(new CallabelTask("task_"+(++i))) 之后并没有阻塞,而是继续往下执行println语句打印出语句: 

All the tasks have been submited through invokeAll method!

      而提交的任务将由其他线程在“将来某个时刻“去执行。当然在主线程去获取执行结果f.get() 的时候肯定是要阻塞的,因为既然要获取结果了,当然要等到任务执行完毕返回才有啊!

如果把上面的CallabelTask改变成RunnableTask,则返回的结果将是null,原因是提交的时候在new TaskFor方法中就已经指定了返回结果为null 

 

class RunnableTask implements Runnable{
		String name;
		public RunnableTask(String name){
			this.name = name;
		}
		@Override
		public void run() {
			System.out.println("Start to execute the task " + name);
			try {
				TimeUnit.SECONDS.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
//RunnableTask 执行结果:
All the tasks have been submited through invokeAll method!
Start to execute the task task_1
Start to execute the task task_5
Start to execute the task task_3
Start to execute the task task_4
Start to execute the task task_2
null
null
null
null
null

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值