首页 > 其他分享 >获取线程的执行结果

获取线程的执行结果

时间:2024-07-18 19:41:14浏览次数:6  
标签:Callable 获取 任务 Future 线程 FutureTask 执行 public

无返回值的 Runnable

public interface Runnable {
    public abstract void run();
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
    // 创建一个包含5个线程的线程池
    ExecutorService executorService = Executors.newFixedThreadPool(5);

    // 创建一个Runnable任务
    Runnable task = new Runnable() {
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    };

    // 提交任务到ExecutorService执行
    for (int i = 0; i < 10; i++) {
        executorService.submit(task);
    }

    // 关闭ExecutorService,不再接受新的任务,等待所有已提交的任务完成
    executorService.shutdown();
}

有返回值的 Callable

public interface Callable<V> {
    V call() throws Exception;
}

Callable 一般配合 ExecutorService 接口使用,它是 Java 线程池框架的核心接口,用来异步执行任务。它提供了一些关键方法用来进行线程管理。

  • submit 方法既可以传入 Runnable 接口也可以传入 Callable接口
public static void main(String[] args) throws ExecutionException, InterruptedException {
    // 创建一个包含5个线程的线程池
    ExecutorService executorService = Executors.newFixedThreadPool(5);

    // 创建一个Callable任务
    Callable<String> task = new Callable<String>() {
        @Override
        public String call() throws Exception {
            return Thread.currentThread().getName();
        }
    };

    // 提交任务到ExecutorService执行,并获取Future对象
    Future[] futures = new Future[10];
    for (int i = 0; i < 10; i++) {
        futures[i] = executorService.submit(task);
    }

    // 通过Future对象获取任务的结果
    for (int i = 0; i < 10; i++) {
        System.out.println(futures[i].get());
    }

    // 关闭ExecutorService,不再接受新的任务,等待所有已提交的任务完成
    executorService.shutdown();
}

异步计算结果 Future 接口

public interface Future<V> {
    // 用来取消任务,如果取消任务成功则返回 true,如果取消任务失败则返回 false。参数 mayInterruptIfRunning 表示是否允许取消正在执行却没有执行完毕的任务,如果设置 true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论 mayInterruptIfRunning 为 true 还是 false,此方法肯定返回 false,即如果取消已经完成的任务会返回 false;如果任务正在执行,若 mayInterruptIfRunning 设置为 true,则返回 true,若 mayInterruptIfRunning 设置为 false,则返回 false;如果任务还没有执行,则无论 mayInterruptIfRunning 为 true 还是 false,肯定返回 true。
    boolean cancel(boolean mayInterruptIfRunning);
    // 表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true
    boolean isCancelled();
    // 表示任务是否已经完成,若任务完成,则返回 true
    boolean isDone();
    // 用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回
    V get() throws InterruptedException, ExecutionException;
    // 用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回 null
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

Future 提供了三种功能:

  • 1)判断任务是否完成;
  • 2)能够中断任务;
  • 3)能够获取任务执行结果。

FutureTask 是 Future 接口的一个唯一实现类,前面的例子中 executorService.submit() 返回的就是 FutureTask

异步计算结果 FutureTask 实现类

// 继承了 Runnable 接口和 Future 接口,而 FutureTask 实现了 RunnableFuture 接口。所以它既可以作为 Runnable 被线程执行,又可以作为 Future 得到 Callable 的返回值。
public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}
public class FutureTask<V> implements RunnableFuture<V> {
    public FutureTask(Callable<V> callable) {}

    public FutureTask(Runnable runnable, V result) {}
    ...
}

当需要异步执行一个计算并在稍后的某个时间点获取其结果时,就可以使用 FutureTask

public static void main(String[] args) throws ExecutionException, InterruptedException {
    // 创建一个固定大小的线程池
    ExecutorService executorService = Executors.newFixedThreadPool(3);

    // 创建一系列 Callable
    Callable<Integer>[] tasks = new Callable[5];
    for (int i = 0; i < tasks.length; i++) {
        final int index = i;
        tasks[i] = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                TimeUnit.SECONDS.sleep(index + 1);
                return index + 1;
            }
        };
    }

    // 将 Callable 包装为 FutureTask,并提交到线程池
    FutureTask<Integer>[] futureTasks = new FutureTask[tasks.length];
    for (int i = 0; i < tasks.length; i++) {
        futureTasks[i] = new FutureTask<>(tasks[i]);
        executorService.submit(futureTasks[i]);
    }

    // 获取任务结果
    for (int i = 0; i < futureTasks.length; i++) {
        System.out.println("Result of task" + (i + 1) + ": " + futureTasks[i].get());
    }

    // 关闭线程池
    executorService.shutdown();
}

标签:Callable,获取,任务,Future,线程,FutureTask,执行,public
From: https://www.cnblogs.com/sprinining/p/18310301

相关文章

  • java map 是线程安全吗 map的线程安全实现类 推荐使用 ConcurrentHashMap
    javamap是线程安全吗map的线程安全实现类推荐使用ConcurrentHashMapHashMap线程安全的吗?Java中平时用的最多的Map集合就是HashMap了,它是线程不安全的。看下面两个场景:1、当用在方法内的局部变量时,局部变量属于当前线程级别的变量,其他线程访问不了,所以这时也不存在线程安全......
  • [php命令执行函数]详解各种php命令执行函数
    如下几种命令执行函数:目录systemexcpassthrushell_exec反引号``popensystemsystem函数简介:用于执行命令语法形式:system(string$command,int$return_var=?)command:必选参数,字符类型,被system函数执行的命令,如lsreturn_var:可选参数,整数类型,如果提供此参数,则com......
  • Java多线程入门
    创建线程的三种方式继承Thread类classMyThreadextendsThread{@Overridepublicvoidrun(){for(inti=0;i<100;i++){System.out.println(getName()+""+i);}}publicstaticvoidmain(String[]args......
  • 多线程三-线程安全之可见性与有序性
    volatile关键字来确保线程间的可见性,可以利用线程可见性在某些场景进行无锁化编程。下载Hotspot源码:官网:https://openjdk.org/左侧菜单,SourceCode下面的Mecurial点击jdk8点击hotspot点击zipvolatile关键字来确保线程间的可见性,可以利用线程可见性在某些场景进行无锁化......
  • @Transactional 中使用线程锁导致了锁失效
     当线程A将level设置为99时,此时锁已经释放了,但是事务还没提交!!线程B此时可以获取到锁并进行查询,查询出来的level还是线程A修改之前的100,所以出现了并发问题。 解决方案1、@Transactional单独一个方法privateLocklock=newReentrantLock();@Transactionalpublicvoid......
  • 线程池的执行流程
    线程池的执行流程是一个系统且有序的过程,它主要涉及到任务的提交、线程的分配、任务的执行以及线程的回收等多个环节。以下是对线程池执行流程的详细阐述:一、任务提交提交任务:当一个新的线程任务被提交到线程池时,线程池会首先尝试在线程池中分配一个空闲线程来执行这个任务。......
  • 过滤器(Filter)和拦截器(Interceptor)的执行顺序和区别
    https://www.cnblogs.com/kuotian/p/13176186.html过滤器FilterFilter有如下几个用处。Filter有如下几个种类。javax.servlet.Filter接口1.通过@WebFilter注解配置2.通过@Bean来配置3.SpringMVC在web.xml配置过滤器启动测试拦截器InterceptorHandlerIn......
  • 探索Nuxt.js的useFetch:高效数据获取与处理指南
    title:探索Nuxt.js的useFetch:高效数据获取与处理指南date:2024/7/15updated:2024/7/15author:cmdragonexcerpt:摘要:“探索Nuxt.js的useFetch:高效数据获取与处理指南”详述了Nuxt.js中useFetch函数的使用,包括基本用法、动态参数获取、拦截器使用,及参数详解。文章......
  • Java中的并发数据结构与多线程优化技术
    Java中的并发数据结构与多线程优化技术大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在多线程编程中,并发数据结构和优化技术是提高系统性能和可靠性的关键。Java提供了丰富的并发数据结构和多线程优化技术,本文将详细介绍常用的并发数据结构及其使用方法......
  • MySQL如何优雅的执行DDL
    一、前言关于MySQLDDL表结构变更,各个工单平台基本上都支持了pt-osc及OnlineDDL的方式,但是,我相信仍然有一大部分人,不太了解这两种方式各自的优缺点是啥,以至于实际当中,会稀里糊涂的随机选一种去执行,选对了固然好,选错了,自然免不了领导的一顿K,这......当然是开玩笑的哈。 在各......