zoukankan      html  css  js  c++  java
  • Java线程之Callable、Future

    在这里插入图片描述

    简述

    在多线程中有时候我们希望一个线程执行完毕后可以返回一些值,在java5中引入了java.util.concurrent.Callable接口,它类似于Runnable接口,但是Callable可以有返回值。

    Java Callable接口使用通用定义对象的返回类型,executor类提供了在线程池中执行Java调用的有用方法,由于可调用任务并行运行,所以我们必须等待返回的对象。

    Future

    实现接口Callable的任务返回的是java.util.concurrent.Future对象,使用Future对象我们可以获得返回值

    #取消任务的运行
    #如果任务已经完成或已经被取消或因某种原因不能被取消,当调用该方法时会失败
    #如果任务还没启动,调用该方法后,该任务将永远不会执行
    #如果任务已经启动,如果参数mayInterruptIfRunning为ture,将会中断任务,否则会允许任务执行完成
    boolean cancel(boolean mayInterruptIfRunning);
    
    #判断任务是否已经取消
    boolean isCancelled();
    
    #判断任务是否执行完成
    boolean isDone();
    #等待获取任务执行完成后的返回值
    V get() throws InterruptedException, ExecutionException;
    
    #在指定时间内等待任务完成并获取返回值,否则抛出超时异常
    V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    

    事例

    下面是一个简单的Callable调用任务示例,它返回在一秒钟后执行任务的线程的名称,我们使用Executor框架来并行执行100个任务,并使用Java Future来获得提交的任务的结果。

    package com.lkf.mulithread;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.concurrent.*;
    
    public class MyCallable implements Callable<String> {
    
        @Override
        public String call() throws Exception {
            Thread.sleep(1000);
            //返回当前线程名字
            return Thread.currentThread().getName();
        }
    
        public static void main(String args[]){
    
            //使用Executors创建一个固定大小的线程池,线程池大小为10
            ExecutorService executor = Executors.newFixedThreadPool(10);
            //创建一个列表来保存与Callable相关的Future对象
            List<Future<String>> list = new ArrayList<Future<String>>();
            //创建 MyCallable 实例
            Callable<String> callable = new MyCallable();
            for(int i=0; i< 100; i++){
                //提交任务到线程池
                Future<String> future = executor.submit(callable);
                //将返回值放入集合
                list.add(future);
            }
            for(Future<String> fut : list){
                try {
    
                    //打印返回值,注意这时会有延时,因为Future.get()要等待任务完成
                    System.out.println(new Date()+ "::"+fut.get());
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
            //关闭线程池
            executor.shutdown();
        }
    
    }
    
    

    当我们运行上边的代码,你会发现输出会有延时,那是因为Future get()方法需要等待任务执行完成。同时我们注意到,每次只有10个线程在执行任务。
    输出结果:

    Sun Mar 25 14:09:50 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:51 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:52 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:53 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:54 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:55 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:56 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:57 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:58 CST 2018::pool-1-thread-7
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-6
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-2
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-9
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-4
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-5
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-8
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-10
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-1
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-3
    Sun Mar 25 14:09:59 CST 2018::pool-1-thread-6
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-2
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-9
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-7
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-4
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-5
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-10
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-8
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-3
    Sun Mar 25 14:10:00 CST 2018::pool-1-thread-1
    

    翻译: https://www.journaldev.com/1090/java-callable-future-example?utm_source=website&utm_medium=sidebar&utm_campaign=Core-Java-Sidebar-Widget

  • 相关阅读:
    九度OJ 1168:字符串的查找删除 (查找)
    九度OJ 1167:数组排序 (排序)
    九度OJ 1166:迭代求立方根 (迭代)
    九度OJ 1165:字符串匹配 (模式匹配)
    九度OJ 1164:旋转矩阵 (矩阵运算)
    九度OJ 1163:素数 (素数)
    九度OJ 1162:I Wanna Go Home(我想回家) (最短路径)
    九度OJ 1161:Repeater(复制器) (递归)
    九度OJ 1160:放苹果 (DFS)
    Sub-process /usr/bin/dpkg returned an error code (1)错误解决办法
  • 原文地址:https://www.cnblogs.com/liukaifeng/p/10052657.html
Copyright © 2011-2022 走看看