• Callable使用示例


    之前工作中也有使用过Callable,但是却没有使用Thread对象去操作过,今晚 小组培训,涨知识了,现特意记录一下,以免忘记.

    先看一下Thread的构造器

     可以看到,Thread类并没有提供参数是Callable的构造器, 但是Runnable是有的.

    再看下面类关系图

       

    所以,我们在使用Thread对象操作Callable实例时,完全可以使用FutureTask去包装一下下.

    示例代码

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    /**
     * 使用Callable示例
     */
    public class FutureTest {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int total = 0;
                    for (int j = 0; j < 100; j++) {
                        System.out.println("total = "+ total);
                        total += j;
                    }
                    return total;
                }
            });
    
            Thread thread = new Thread(task);
            thread.start();
    
            Integer total = task.get();
    
            System.out.println("求和:" + total);
        }
    }

    在工作中,我们大多使用线程池对象操作Callable任务,并且获取任务返回值. 其实jdk提供的线程池ThreadPoolExecutor类操作Callable任务也是通过FutureTask类来包装的,

    下面是源码

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

    涨知识了吧....

    一下取消任务的正确姿势

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    /**
     * 使用Callable示例
     */
    public class FutureTest {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int total = 0;
                    for (int j = 0; j < 100; j++) {
                        if (Thread.currentThread().isInterrupted()) {
                            System.out.println("取消任务...");
                            return null;
                        }
                        System.out.println("total = " + total);
                        total += j;
                    }
                    return total;
                }
            });
    
            Thread thread = new Thread(task);
            thread.start();
    //        便于测试观察,主线程睡1ms
            Thread.currentThread().sleep(1);
    //        取消任务
            task.cancel(true);
        }
    }    





    task.cancle(true): 该方法并不会真正的取消任务,它只会给任务线程打上一个终断的标识,相当于说,主线程说你可以停了....
    Thread.currentThread().isInterrupted() : 任务线程检测自个身上是否有终断标识,如果发现有终断任务的标识, 好吧,我不干了,结束任务....
     
  • 相关阅读:
    更改ORACLE_HOME_NAME
    Linux 查看裸设备大小
    Linux 日常操作
    Linux 高 wio 分析
    Linux 大页: HugePage 与transparent HugePage
    CentOS 8 配置本地YUM源
    MySQL 表压缩
    HIVE 处理json结构数据
    Emacs org-mode 2 文档结构
    CentOS 7 Oracle 19.3 单实例静默安装
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/12032455.html
Copyright © 2020-2023  润新知