精华内容
下载资源
问答
  • FutureTask

    2021-07-03 09:34:32
    FutureTask 多线程执行任务时,有比较耗时操作,但又需要其返回结果时,可以使用FutureTask public class FutureTaskDemo { public static void main(String[] args) throws Exception { FutureTask<String>...

    FutureTask

    多线程执行任务时,有比较耗时操作,但又需要其返回结果时,可以使用FutureTask

    public class FutureTaskDemo {
    
        public static void main(String[] args) throws Exception {
            FutureTask<String> futureTask = new FutureTask<String>(() -> {
                log.info("do something in callable");
                Thread.sleep(5000);
                return "Done";
            });
    
            new Thread(futureTask).start();
            log.info("do something in main");
            Thread.sleep(1000);
            // 获取耗时操作的返回结果,这里是堵塞操作
            String result = futureTask.get();
            log.info("result:{}", result);
        }
    }
    
    展开全文
  • futureTask

    2018-01-24 22:49:39
    FutureTask可以把它当作是闭锁的一种(FutureTask的实现描述了一个抽象的可携带结果的计算)。 FutureTask的通过Callable实现的(带返回值的Runnable),并且有3个状态:等待、运行和完成。 完成包括:正常结束、取消...
    FutureTask可以把它当作是闭锁的一种(FutureTask的实现描述了一个抽象的可携带结果的计算)。
    
    FutureTask的通过Callable实现的(带返回值的Runnable),并且有3个状态:等待、运行和完成。
    完成包括:正常结束、取消和异常。一旦FutureTask进入完成状态,它会永远停止在这个状态上。

    boolean cancel(boolean mayInterruptIfRunning);
    参数为true时,强制中断当前任务。
    boolean isCancelled();
    如果任务被取消返回true。
    boolean isDone();
    判断是否完成,而完成状态就是上面的3个状态。
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
    可以中断、超时

    使用场景:银行需要实时导出截止到当前时间的财务报表(除了当天的数据都已经固化好了,那么比较耗时的计算就是当天的数据)
    样例:
    public static void main (String[] args)
    {
    FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>()
    {
    @Override public Integer call () throws Exception
    {
    System.out.println(Thread.currentThread().getName() + "操作比较耗时的当前数据计算~~~");
    Thread.sleep(new Random().nextInt(5000));
    int localData = new Random().nextInt(100);
    System.out.println("耗时计算返回结果~~~" + localData);
    return localData;
    }
    });
    new Thread(task).start();
    Integer fixData = 1;
    Integer localData = 0;
    try
    {
    System.out.println(Thread.currentThread().getName() + "获取固化好的数据开始~~~");
    Thread.sleep(new Random().nextInt(1000));
    System.out.println(Thread.currentThread().getName() + "获取固化好的数据结束~~~~");
    while (!task.isDone())
    {
    System.out.println("耗时计算还在进行中~~~~请等待!!");
    Thread.sleep(1000);
    }


    System.out.println(Thread.currentThread().getName() + "做聚合操作~~~~");
    localData = task.get();
    Integer result = fixData + localData;
    System.out.println(Thread.currentThread().getName() + "返回报表数据~~~~" + result);
    } catch (InterruptedException e)
    {
    e.printStackTrace();
    } catch (ExecutionException e)
    {
    e.printStackTrace();
    }
    }

    结果打印
    main获取固化好的数据开始~~~
    Thread-0操作比较耗时的当前数据计算~~~
    main获取固化好的数据结束~~~~
    耗时计算还在进行中~~~~请等待!!
    耗时计算还在进行中~~~~请等待!!
    耗时计算还在进行中~~~~请等待!!
    耗时计算还在进行中~~~~请等待!!
    耗时计算返回结果~~~81
    main做聚合操作~~~~
    main返回报表数据~~~~82



    展开全文
  • futuretask

    2019-07-30 13:44:02
    import java.util.concurrent.Callable;...import java.util.concurrent.FutureTask; /** * Created by yuzhimin */ public class FutureTest { public static void main(String[] args){ long star...
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.FutureTask;
    
    /**
     * Created by yuzhimin
     */
    public class FutureTest {
        public static void main(String[] args){
            long startTime = System.currentTimeMillis();
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(3000);
                    return "aaa";
                }
            };
    
            FutureTask<String> futureTask = new FutureTask<>(callable);
            new Thread(futureTask).start();
    
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
            }
    
            if (futureTask.isDone()) {
                System.out.println("futuretask done");
            } else {
                System.out.println("futuretask not done");
            }
    
            System.out.println("1221");
    
            try {
                System.out.println("child thread value:"+futureTask.get());
            } catch (Exception e) {
            }
    
            System.out.println("总耗时:"+(System.currentTimeMillis()-startTime));
        }
    }
    
    
    
    import java.util.concurrent.*;
    
    /**
     * Created by yuzhimin
     */
    public class ExecutorCompletionTest {
    
        static String doSomething(String somebody,long sleepTimestamp){
            try {
                Thread.sleep(sleepTimestamp);
            } catch (Exception e){
            }
    
            return somebody;
        }
    
        public static void main(String[] args) {
            long starttime = System.currentTimeMillis();
            ExecutorService executor = Executors.newCachedThreadPool();
            ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(executor);
    
            completionService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // TODO Auto-generated method stub
                    return doSomething("B",8000);
                }
    
            });
    
            completionService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // TODO Auto-generated method stub
                    return doSomething("A",4000);
                }
            });
    
            int threadsize = 2;
    
            for (int i = 0; i < threadsize; i++) {
                try {
                    Future<String> future = completionService.take();
                    String result = future.get();
                    System.out.println(result+"总耗时:"+(System.currentTimeMillis()-starttime));
                } catch (Exception e) {
    
                }
            }
            System.out.println("all耗时:"+(System.currentTimeMillis()-starttime));
            executor.shutdown();
        }
    }
    
    展开全文
  • FutureTask详解

    万次阅读 多人点赞 2019-06-03 22:10:24
    FutureTask介绍 一个可取消的异步计算。FutureTask提供了对Future的基本实现,可以调用方法去开始和取消一个计算,可以查询计算是否完成并且获取计算结果。只有当计算完成时才能获取到计算结果,一旦计算完成,计算...

    FutureTask介绍

    一个可取消的异步计算。FutureTask提供了对Future的基本实现,可以调用方法去开始和取消一个计算,可以查询计算是否完成并且获取计算结果。只有当计算完成时才能获取到计算结果,一旦计算完成,计算将不能被重启或者被取消,除非调用runAndReset方法。
    除了实现了Future接口以外,FutureTask还实现了Runnable接口,因此FutureTask交由Executor执行,也可以直接用线程调用执行(futureTask.run())。根据FutureTask的run方法执行的时机,FutureTask可以处于以下三种执行状态:
    1、未启动:在FutureTask.run()还没执行之前,FutureTask处于未启动状态。当创建一个FutureTask对象,并且run()方法未执行之前,FutureTask处于未启动状态。
    2、已启动:FutureTask对象的run方法启动并执行的过程中,FutureTask处于已启动状态。
    3、已完成:FutureTask正常执行结束,或者FutureTask执行被取消(FutureTask对象cancel方法),或者FutureTask对象run方法执行抛出异常而导致中断而结束,FutureTask都处于已完成状态。
    FutureTask状态迁移图
    在这里插入图片描述当FutureTask处于未启动或者已启动的状态时,调用FutureTask对象的get方法会将导致调用线程阻塞。当FutureTask处于已完成的状态时,调用FutureTask的get方法会立即放回调用结果或者抛出异常。
    当FutureTask处于未启动状态时,调用FutureTask对象的cancel方法将导致线程永远不会被执行;当FutureTask处于已启动状态时,调用FutureTask对象cancel(true)方法将以中断执行此任务的线程的方式来试图停止此任务;当FutureTask处于已启动状态时,调用FutureTask对象cancel(false)方法将不会对正在进行的任务产生任何影响;当FutureTask处于已完成状态时,调用FutureTask对象cancel方法将返回false;
    FutureTask的get和cancel的执行示意图
    在这里插入图片描述

    FutureTask使用

    可以把FutureTask交给Executor执行;也可以通ExecutorService.submit(…)方法返回一个FutureTask,然后执行FutureTask.get()方法或FutureTask.cancel(…)方法。除此以外,还可以单独使用FutureTask。
    当一个线程需要等待另一个线程把某个任务执行完后它才能继续执行,此时可以使用FutureTask。假设有多个线程执行若干任务,每个任务最多只能被执行一次。当多个线程试图同时执行同一个任务时,只允许一个线程执行任务,其他线程需要等待这个任务执行完后才能继续执行。下面是对应的示例代码。

    private final ConcurrentMap<Object, Future<String>> taskCache = new ConcurrentHashMap<>();
    
        private String executionTask(final String taskName)throws ExecutionException, InterruptedException {
            while (true) {
                Future<String> future = taskCache.get(taskName); // 1.1,2.1
                if (future == null) {
                    Callable<String> task = () -> taskName;
                    FutureTask<String> futureTask = new FutureTask<>(task);
                    future = taskCache.putIfAbsent(taskName, futureTask); // 1.3
                    if (future == null) {
                        future = futureTask;
                        futureTask.run(); // 1.4执行任务
                    }
                }
                try {
                    return future.get(); // 1.5,
                } catch (CancellationException e) {
                    taskCache.remove(taskName, future);
                }
            }
        }
    

    在这里插入图片描述当两个线程试图同时执行同一个任务时,如果Thread 1执行1.3后Thread 2执行2.1,那么接下来Thread 2将在2.2等待,直到Thread 1执行完1.4后Thread 2才能从2.2(FutureTask.get())返回

    FutureTask实现

    jdk1.8的FutureTask有个说明:
    修订说明:这与这个类以前依赖AbstractQueuedsynchronizer的版本不同,主要是为了避免在取消竞争期间保留中断状态让用户感到意外。在当前的设计中,Sync控件依赖于通过CAS更新的“state”字段来跟踪完成,以及一个简单的Treiber堆栈来保存等待的线程。
    风格注意:与往常一样,我们绕过了使用 AtomicXFieldUpdaters的开销,而是直接使用Unsafe。

    Future

    FutureTask实现了Future接口,Future接口有5个方法:
    1、boolean cancel(boolean mayInterruptIfRunning)
    尝试取消当前任务的执行。如果任务已经取消、已经完成或者其他原因不能取消,尝试将失败。如果任务还没有启动就调用了cancel(true),任务将永远不会被执行。如果任务已经启动,参数mayInterruptIfRunning将决定任务是否应该中断执行该任务的线程,以尝试中断该任务。
    如果任务不能被取消,通常是因为它已经正常完成,此时返回false,否则返回true
    2、boolean isCancelled()
    如果任务在正常结束之前被被取消返回true
    3、boolean isDone()
    正常结束、异常或者被取消导致任务完成,将返回true
    4、V get()
    等待任务结束,然后获取结果,如果任务在等待过程中被终端将抛出InterruptedException,如果任务被取消将抛出CancellationException,如果任务中执行过程中发生异常将抛出ExecutionException。
    5、V get(long timeout, TimeUnit unit)
    任务最多在给定时间内完成并返回结果,如果没有在给定时间内完成任务将抛出TimeoutException。

    FutureTask状态转换

    FutureTask有以下7中状态:
    在这里插入图片描述
    FutureTask任务的运行状态,最初为NEW。运行状态仅在set、setException和cancel方法中转换为终端状态。在完成过程中,状态可能呈现出瞬时值INTERRUPTING(仅在中断运行程序以满足cancel(true)的情况下)或者COMPLETING(在设置结果时)状态时。从这些中间状态到最终状态的转换使用成本更低的有序/延迟写,因为值是统一的,需要进一步修改。
    state:表示当前任务的运行状态,FutureTask的所有方法都是围绕state开展的,state声明为volatile,保证了state的可见性,当对state进行修改时所有的线程都会看到。
    NEW:表示一个新的任务,初始状态
    COMPLETING:当任务被设置结果时,处于COMPLETING状态,这是一个中间状态。
    NORMAL:表示任务正常结束。
    EXCEPTIONAL:表示任务因异常而结束
    CANCELLED:任务还未执行之前就调用了cancel(true)方法,任务处于CANCELLED
    INTERRUPTING:当任务调用cancel(true)中断程序时,任务处于INTERRUPTING状态,这是一个中间状态。
    INTERRUPTED:任务调用cancel(true)中断程序时会调用interrupt()方法中断线程运行,任务状态由INTERRUPTING转变为INTERRUPTED

    可能的状态过渡:
     1、NEW -> COMPLETING -> NORMAL:正常结束
     2、NEW -> COMPLETING -> EXCEPTIONAL:异常结束
     3、NEW -> CANCELLED:任务被取消
     4、NEW -> INTERRUPTING -> INTERRUPTED:任务出现中断
    
    展开全文
  • FutureTask原始码解析 一,FutureTask是什么? FutureTask是可取消的异步的计算任务,它可以通过线程池和线程对象执行,一般来说是FutureTask用于耗时的计算。 二,FutureTask继承图 三,未来任务源码 FutureTask的...
  • FutureTask使用

    2021-08-08 18:20:14
    FutureTask使用 FutureTask介绍 FutureTask 表示一个异步运算的任务。FutureTask 里面可以传入一个 Callable 的具体实现类,可以对这个异步运算的任务的结果进行等待获取、判断是否已经完成、取消任务等操作。 ...
  • FutureTask用法

    2019-04-25 18:30:53
    FutureTask用法 FutureTask可用于异步获取执行结果或取消执行任务的场景。通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过FutureTask的get方法异步获取...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,337
精华内容 21,334
关键字:

futuretask