java多线程Future和Callable类示例分享

标题:Java多线程Future和Callable类示例分享

什么是Java的Future和Callable类?

在Java多线程编程中,使用Future和Callable类可以方便地处理异步任务,也可以获取异步任务的结果。

Callable是一个函数式接口,它描述的是具有返回值的任务。可以通过实现Callable接口并实现它的call()方法来定义自己的任务,该方法将在调用时返回一个Future对象。Future对象表示异步计算的结果,可以使用get()方法等待计算完成并返回结果。

Future和Callable的基本用法

下面是一个简单的示例代码,说明如何使用Future和Callable类:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class MyCallable implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println("Callable is running...");
        Thread.sleep(2000);
        return 123;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        MyCallable callable = new MyCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);

        Thread t = new Thread(futureTask);
        t.start();

        System.out.println("主线程在执行其他任务");

        Thread.sleep(500);

        System.out.println("主线程在等待结果");
        System.out.println("FutureTask的结果为:" + futureTask.get());
    }

}

我们首先定义了一个实现了Callable接口的MyCallable类,该类的call()方法会返回一个整数123。然后,我们创建一个FutureTask对象,将MyCallable对象的实例传递给它。FutureTask类实际上是一个RunnableFuture实现类,它可以被线程执行。

在主线程中,我们首先启动了一个线程来执行该任务,然后在等待任务执行结果之前,主线程可以执行其他任务,不必等待任务执行完毕的结果。当需要任务执行结果时,可以通过futureTask.get()方法来获取结果。如果任务还未完成,futureTask.get()会使当前线程阻塞,等待任务完成后返回结果。如果任务已经完成,get()方法会立即返回结果。

使用Future和Callable类实现带超时时间的任务

有时候我们需要在任务执行一定时间后就停止该任务,比如用户停止了一个无限循环的计算任务。我们可以通过使用Future和ScheduledExecutorService来实现带超时时间的任务。

下面是一个示例代码,它会执行一个计算斐波那契数列的任务,该任务是一个无限循环,但是我们设置了执行时间,如果任务执行时间超过规定时间,则抛出TimeoutException异常。

import java.util.concurrent.*;

public class TimeoutCallable implements Callable<Long> {

    @Override
    public Long call() throws Exception {
        long i = 0;
        while (true) {
            i++;
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Callable被中断了...");
                throw new InterruptedException("Callable被中断了...");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        TimeoutCallable timeoutCallable = new TimeoutCallable();
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Long> future = executor.submit(timeoutCallable);

        try {
            Long result = future.get(3, TimeUnit.SECONDS);
            System.out.println("结果是:" + result);
        } catch (TimeoutException e) {
            System.out.println("超时了...");
            future.cancel(true);
        }
        executor.shutdownNow();
    }

}

我们定义了一个实现Callable接口的TimeoutCallable类,该任务将会一直循环,直到被中断。我们使用ExecutorService创建了一个单线程池,并将TimeoutCallable对象交给它执行。

在main()方法中,我们调用future.get(3, TimeUnit.SECONDS)方法等待任务执行结果,但是我们将等待时间设置为3秒钟。如果任务没有在3秒钟内完成,就会抛出TimeoutException异常,我们可以通过该异常处理机制来取消任务执行并停止该任务。

通过这两个示例,我们可以看到Future和Callable类的基本用法和带超时时间执行任务的机制。使用Future和Callable类可以很方便地异步处理任务,也可以优雅地处理任务执行结果和异常。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程Future和Callable类示例分享 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • java-jsp springmvc-controller 传值到页面的方法

    下面是完整的攻略: Java JSP SpringMVC Controller传值到页面的方法 在Java Web开发中,SpringMVC是一种常用的框架。在开发过程中,我们经常需要在Controller中处理数据,然后将处理后的数据传递到页面中进行渲染。本文将介绍SpringMVC Controller传值到页面的几种方法。 1. Model和Model…

    Java 2023年6月15日
    00
  • Java Map所有的值转为String类型

    要将Java Map中的所有值转换为String类型,可以采用以下步骤: 获取Map中所有的键值对 遍历所有的键值对,将值转换为String类型 以下是一个实现这个过程的Java示例代码: Map<String, Object> map = new HashMap<String, Object>(); map.put("ke…

    Java 2023年5月20日
    00
  • Spring MVC过滤器-登录过滤的代码实现

    Spring MVC过滤器-登录过滤的代码实现 Spring MVC是一种基于Java的Web框架,它提供了许多便捷的功能和工具,使得开发者可以更加高效地开发Web应用程序。其中,过滤器是Spring MVC中常用的一种技术,本文将详细讲解如何在Spring MVC中实现登录过滤,并提供两个示例来说明如何实现这一过程。 步骤一:创建Spring MVC项目 …

    Java 2023年5月17日
    00
  • springboot自定义starter启动器的具体使用实践

    Spring Boot自定义Starter启动器的具体使用实践 在本文中,我们将详细讲解如何使用Spring Boot自定义Starter启动器,包括创建Starter、定义自动配置、使用自定义Starter等。 创建Starter 创建自定义Starter的第一步是创建一个Maven项目,并添加以下依赖: <dependency> <gr…

    Java 2023年5月15日
    00
  • Springboot启动不检查JPA的数据源配置方式

    启动时不检查数据源配置可以使用Springboot的一些特定属性来实现。在Springboot中,这些属性主要定义在application.properties(或者application.yml)文件中。为了实现启动时不检查数据源配置,需要在这些文件中添加以下内容: spring.datasource.continue-on-error=true spri…

    Java 2023年5月20日
    00
  • Java判断对象是否为空(包括null ,””)的方法

    判断对象是否为空是Java开发中非常常见的操作,正确的判断方式可以避免很多空指针异常的出现。以下是几种常见的判断对象是否为空的方法。 1.使用“==”运算符判断是否为null 在Java中,使用“==”运算符判断对象是否为null是最常用的方式,代码示例如下: Object obj = null; if (obj == null) { // 对象为空 } e…

    Java 2023年5月26日
    00
  • Java并发包工具类CountDownLatch的应用详解

    Java并发包工具类CountDownLatch的应用详解 CountDownLatch概述 CountDownLatch是java.util.concurrent包中提供的一个并发工具类,常用于控制多个线程等待一组事件的发生,直到所有的线程都达到某个状态后才能同时执行。 在CountDownLatch中,需要设定一个计数器,该计数器初始值为线程的数量,每个…

    Java 2023年5月19日
    00
  • 将应用程序进行Spring6迁移的最佳使用方式

    将应用程序进行Spring 6迁移的最佳使用方式的步骤: 1. 了解Spring 6的新特性 在进行Spring 6迁移之前,应该先确保已经掌握了Spring 6的新特性。Spring 6带来了许多新功能,例如Spring WebFlux、Spring Security OAuth 2.0和Spring Cloud Function等。了解这些新特性可以帮助…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部