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日

相关文章

  • Sprint Boot @CachePut使用方法详解

    在Spring Boot中,@CachePut注解用于将方法的返回值存储到缓存中。使用@CachePut注解可以在方法执行后将结果缓存起来,以便下次使用相同的参数调用该方法时,可以直接从缓存中获取结果,而不必再次执行该方法。本文将详细介绍@CachePut注解的作用和使用方法,并提供两个示例说明。 @CachePut注解的作用 在Spring Boot中,@…

    Java 2023年5月5日
    00
  • SpringMVC+MyBatis分页(最新)

    以下是关于“SpringMVC+MyBatis分页(最新)”的完整攻略,其中包含两个示例。 1. 前言 在Web应用程序中,分页是一种常见的需求。在SpringMVC和MyBatis中,可以使用PageHelper插件来实现分页。本攻略将详细讲解如何使用SpringMVC和MyBatis实现分页。 2. 添加PageHelper依赖 在使用PageHelpe…

    Java 2023年5月16日
    00
  • Java常用命令汇总

    Java常用命令汇总攻略 Java是一种高级编程语言,由于其稳定性和跨平台性能备受欢迎,因此成为了许多软件的首选语言。针对Java的常用命令,本文旨在为初学者提供帮助以及提高Java编程效率。下面将对Java常用命令进行详细讲解。 Java编译命令 Java编写的代码在开发完成后需要编译成可执行的文件。下面是Java编译命令的格式和用法: javac [op…

    Java 2023年5月19日
    00
  • springboot使用AOP+反射实现Excel数据的读取

    针对“springboot使用AOP+反射实现Excel数据的读取”的完整攻略,我将从以下几个方面进行详细讲解: AOP的介绍 反射的介绍 将AOP和反射结合起来实现Excel数据的读取 示例1:使用AOP+反射实现读取一个Excel文件 示例2:使用AOP+反射实现批量读取多个Excel文件 以下是具体的介绍和示例。 1. AOP的介绍 AOP(Aspec…

    Java 2023年5月20日
    00
  • java web手写实现分页功能

    下面是“Java Web手写实现分页功能”的详细攻略: 1. 前置知识 在手写实现分页功能之前,需要掌握以下知识: JDBC,用于操作数据库 Servlet,用于接收请求和响应数据 JSP,用于在页面上呈现数据 HTML/CSS,用于美化页面 2. 实现思路 根据用户请求的当前页数和每页显示记录数,计算出查询的起始位置和结束位置 使用JDBC从数据库中查询数…

    Java 2023年6月15日
    00
  • 使用Java实现DNS域名解析的简单示例

    下面我将为您详细讲解“使用Java实现DNS域名解析的简单示例”的完整攻略。 什么是DNS? DNS(Domain Name System)是一种将域名转换为IP地址的互联网服务。DNS将人类可读的域名转换为机器可读的IP地址。例如,www.baidu.com域名会被DNS服务器解析为IP地址,例如:220.181.110.6。 Java实现DNS域名解析 …

    Java 2023年5月19日
    00
  • Spring Boot中slf4j日志依赖关系示例详解

    好的!首先,我们来看一下如何在Spring Boot中使用slf4j日志依赖关系。 1. 什么是SLF4J? SLF4J(Simple Logging Facade for Java)是Java日志框架的一个抽象层,它允许应用程序在运行时使用任何日志框架,并且可以在不修改应用程序代码的情况下更改底层的日志框架。 2. 添加slf4j的依赖关系 要在Sprin…

    Java 2023年5月31日
    00
  • Java Socket实现聊天室附1500行源代码

    Java Socket实现聊天室是一种常见的网络应用程序,该应用程序使用Socket API实现了客户端和服务器端之间的连接。本攻略通过讲解如何使用Java Socket API实现一个聊天室,来帮助开发者了解Java Socket编程的基本原理和用法。 概述 Java Socket API是Java语言提供的一个用于网络通信的API,它允许程序员使用Soc…

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