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断点续传实现原理

    下面是关于“很简单的Java断点续传实现原理”的完整攻略。 一、什么是Java断点续传? Java断点续传是指,在下载或上传文件时,出现网络中断等问题导致下载或上传任务中断时,可以通过实现“断点续传”功能,让下载或上传任务从中断的地方继续执行,而不是重新开始。 二、Java断点续传的实现原理 Java断点续传的实现原理是,通过HTTP协议中的range请求头…

    Java 2023年5月19日
    00
  • JavaScript中的其他对象

    JavaScript中的其他对象是指除了基本数据类型(如数字、字符串、布尔值、null、undefined)和数组之外的所有对象。这些对象包括函数、日期、正则表达式、数学和全局对象等。本文将详细讲解这些其他对象的用法及示例。 函数对象 函数对象是JavaScript中的一等公民,可以当作变量被传递、赋值或作为函数的参数和返回值。函数对象有以下几种定义方式: …

    Java 2023年5月30日
    00
  • JavaWeb中struts2实现文件上传下载功能实例解析

    JavaWeb中struts2实现文件上传下载功能实例解析 在JavaWeb应用中,实现文件的上传下载是很常见的需求。而在struts2框架中,实现文件的上传下载也并不难。本文将详细介绍struts2框架中如何实现文件上传下载的功能。 1. 文件上传实现 在struts2框架中,文件上传的实现需要用到Commons-Fileupload和Commons-Io…

    Java 2023年5月20日
    00
  • java Struts2框架下实现文件上传功能

    实现文件上传功能在Web应用程序中非常常见。在Java Web应用程序中,常用的框架之一是Struts2框架。下面是实现文件上传功能的完整攻略。 步骤1:添加依赖 要在Struts2应用程序中实现文件上传功能,我们需要添加一些依赖项。具体来说,我们需要添加以下依赖项: <dependency> <groupId>org.apache.…

    Java 2023年5月20日
    00
  • Java Base64解码错误及解决方法

    Java Base64解码错误及解决方法 背景 Base64是一种将二进制数据编码成ASCII字符可读格式的编码方式,常用于网络传输、数据存储等场景。Java提供了丰富的Base64编解码类库,如java.util.Base64或apache.commons.codec.binary.Base64等。 但在实际应用中,我们可能会遇到Base64解码错误的问题…

    Java 2023年5月20日
    00
  • 一文吃透 Spring 中的 AOP 编程

    一文吃透 Spring 中的 AOP 编程 什么是 AOP AOP(Aspect Oriented Programming)即面向切面编程。与 OOP(面向对象编程)不同,AOP 不是关注代码的对象,而是关注在程序运行过程中“特定点”发生的一些处理。其主要作用是在不修改原有逻辑的情况下,对程序进行一些扩展操作,例如:日志记录、性能监控、事务管理等。 Spri…

    Java 2023年5月19日
    00
  • jsp中sitemesh修改tagRule技术分享

    下面我将详细讲解“JSP中Sitemesh修改tagRule技术分享”的完整攻略。 简介 Sitemesh是一款用于Web页面装饰的框架,可以将公共的页面模板与动态生成的内容进行分离。在使用Sitemesh的过程中,可以通过修改tagRule来自定义标签的使用规则,并且可以根据需求进行灵活调整。 修改tagRule的步骤 1. 创建自定义的tagRule 在…

    Java 2023年6月15日
    00
  • Java中操作数组的Arrays类

    首先,我们需要知道Arrays类是Java中用于操作数组的一个工具类。Arrays类提供了一系列方法用来对数组进行常见的操作,如排序、查找、复制等等。 数组排序 数组排序是我们在实际开发中经常会遇到的一个问题,Java中提供了一些常用的排序算法,如冒泡排序、选择排序等等,Arrays类中提供了很多现成的排序方法,我们只需要简单地调用即可。 下面以sort方法…

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