• java核心知识点----创建线程的第三种方式 Callable 和 Future CompletionService


    前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的.

    Callabel接口可以看成是Runnable接口的增强版,只不过其线程执行体call()方法比run方法更加强大罢了:

    >>call()方法中可以有返回值

    >>call()方法中可以声明抛出异常.

    一.创建线程的第三种方式----使用Callable对象进行创建

    复制代码
    package com.amos.concurrent;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    /**
     * @ClassName: CallableAndFuture
     * @Description: 多线程中的Callable和Future学习
     * @author: amosli
     * @email:hi_amos@outlook.com
     * @date Apr 22, 2014 12:07:26 AM
     */
    public class CallableAndFuture {
        public static void main(String[] args) throws Exception, ExecutionException {
            ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
            Future<String> future = newSingleThreadExecutor.submit(new Callable<String>() {
                public String call() throws Exception {
                    Thread.sleep(20);
                    return "hi,amos";
                }
            });
            // System.out.println("future:"+future.get(1,TimeUnit.MILLISECONDS));//等待指定的时间
            System.out.println("future:" + future.get());
            }
    }
    复制代码

    效果如下:

    注:

    1.这里要注意的是,创建线程时执行任务不是用execute()方法去执行了,而是用submit()方法.

    2.同时要注意,这里call()方法返回值,要和上面的保持一致.

    3.另外,可以设置最大等待时间,就是等待程序的返回值,这里使用get()方法.

    4.其常用的其它方法有cancel(),isCancelled(),isDone(),分别表示取消关联的任务,是否已经取消,任务是否已经完成.

    二.CompeltionService

    CompeltionService主要用于提交一组Callable对象,其take方法用于返回已完成的callable任务的Future对象.可以用麦子收割来作比喻,种了10亩地的麦子,哪一块先成熟先收割哪一块.

    举例:

    复制代码
    package com.amos.concurrent;
    
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class CallableAndFuture {
    
        public static void main(String[] args) throws Exception, ExecutionException {
    ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
            CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(newFixedThreadPool);
            for(int i=0;i<11;i++){//创建10个任务
            final int task=i;
            completionService.submit(new Callable<Integer>() {//提交任务
                public Integer call() throws Exception {
                    Thread.sleep(new Random().nextInt(3000));//最多3秒
                    return task;
                }
            });
            }
            //take
            for(int i=0;i<11;i++){
                System.out.println("已完成的任务:"+completionService.take().get());
            }
    }
    复制代码

    效果如下图所示:

    注:由结果也可以看出来,其随机结果是根据任务的先后完成顺序来的,使用其take()方法可以获取其返回结果.

  • 相关阅读:
    Dijit、ExtJS、jQuery UI 异同浅析
    Sencha Touch和jQuery Mobile该如何选择(转)
    用delphi开发activex打印控件
    组织机构图
    MyBatis自学(1):MyBatis概述
    MyBatis自学(4):动态SQL
    MyBatis自学(3):MyBatis逆向工程
    MyBatis自学(2):MyBatis初识
    MyBatis自学(5):延迟加载
    FileUpload上传图片提示 “GDI+中发生一般性错误”
  • 原文地址:https://www.cnblogs.com/ncy1/p/9164465.html
Copyright © 2020-2023  润新知