Java线程池的结果处理


前言

Java线程池中的Future和FutureTask表示线程的返回结果处理类,本文简单分析Future和实现类的用法。

如何获取线程中的运算结果?

  1. 使用全局变量,将线程中的结果赋值给全局变量
  2. 使用concurrent包中的队列,使用生产者-消费者模式获取线程中的结果
  3. 使用Future或者FutureTask阻塞获取线程结果

Future

Future是获取任务结果和取消任务的顶层接口

Future接口

get():获取任务执行结果,在获取结果之前,该任务阻塞,直到获取结果

get(long,TimeUnit):和get()方法相同,不过设置了超时时间,在超时时间内没有获取结果将阻塞,超过超时时间返回TimeoutException异常

cancel(boolean):尝试取消一个任务

1):如果任务没有开启,则该任务将永远不会执行

2):如果任务正在执行,则通过boolean确定执行该任务的线程是否应该在试图停止该任务时被中断。

3):如果任务已经完成。则取消。

isCancelled():如果任务在正常完成前取消该任务,该方法返回true;

isDone():如果任务正常完成,返回true

FutureTask

FutureTask:是Future的实现类,并且继承了Runable接口

public class FutureTask<V> implements RunnableFuture<V> 

public interface RunnableFuture<V> extends Runnable, Future<V> 

调用run()方法执行该任务

当一个Runnable或者Callable提交给FutureTask的时候。FutureTask存在以下几种状态

1)未启动。FutureTask.run()方法还没有被执行之前,FutureTask处于未启动状态。当创建一个FutureTask,且没有执行FutureTask.run()方法之前,这个FutureTask处于未启动状态。

2)已启动。FutureTask.run()方法被执行的过程中,FutureTask处于已启动状态。

3)已完成。FutureTask.run()方法执行完后正常结束,或被取消(FutureTask.cancel(…)),或执行FutureTask.run()方法时抛出异常而异常结束,FutureTask处于已完成状态。

当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞;

当FutureTask处于已完成状态时,执行FutureTask.get()方法将导致调用线程立即返回结果或抛出异常。

当FutureTask处于未启动状态时,执行FutureTask.cancel()方法将导致此任务永远不会被执行;

当FutureTask处于已启动状态时,执行FutureTask.cancel(true)方法将以中断执行此任务线程的方式来试图停止任务;

当FutureTask处于已启动状态时,执行FutureTask.cancel(false)方法将不会对正在执行此任务的线程产生影响(让正在执行的任务运行完成);当FutureTask处于已完成状态时,执行FutureTask.cancel(…)方法将返回false。

Demo1

Callable提交给线程池,获取结果


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 60,
                TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());

        Future<String> res= threadPoolExecutor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                String str="Future";
                //睡5s
                TimeUnit.SECONDS.sleep(5);
                return str;
            }
        });

        String s = res.get();
        System.out.println(s);
    }

结果;

Future

Demo2

单独一个Callable提交给FutureTask获取结果

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        FutureTask<String> res= new FutureTask<String>(
                new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        String str="Future";
                        TimeUnit.SECONDS.sleep(5);
                        return  str;
                    }
                }
        );
       res.run();
       String str=res.get();
        System.out.println(str);
    }

结果:

Future


文章作者: jackey
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 jackey !
评论
  目录