Java中Runnable和Callable的区别和联系及使用场景

2025-03-18 14:50

本文主要是介绍Java中Runnable和Callable的区别和联系及使用场景,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Java中Runnable和Callable的区别和联系及使用场景》Java多线程有两个重要的接口,Runnable和Callable,分别提供一个run方法和call方法,二者是有较大差异的,本文...

Java多线程有两个重要的接口,Runnable和Callable,分别提供一个run方法和call方法,二者是有较大差异的。

1)Runnable提供run方法,无法通过throws抛出异常,所有CheckedException必须在run方法内部处理。Callable提供call方法,直接抛出Exception异常。

2)Runnable的run方法无返回值,Callable的call方法提供返回值用来表示任务运行的结果

3)Runnable可以作为Thread构造器的参数,通过开启新的线程来执行,也可以通过线程池来执行。而Callable只能通过线程池执行。

一、Runnable使用场景

1)作为Thread的构造参数开启新的线程,以下是常用的通过匿名内部类的方式创建线程。

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("I am a runnable task");
            }
        });
        thread.start();

2)由于Jav编程a只提供单继承,故创建线程时一般通过实现Runnable接口,来实现run方法的具体逻辑。然后实例化,作为Thread的构造参数开启线程。

class RunnableTask implements Runnable {
    @Override
    public void run() {
        System.out.println("I am a runnable task");
    }
}
China编程

main方法:

        RunnableTask runnableTask = new RunnableTask();
        Thread thread1 = new Thread(runnableTask);
        thread1.start();

其实1)和2)的本质是一样的。

3)作为线程任务提交给线程池,通过线程池维护的工作者线程来执行。

        ExecutorService execjavascriptutor = Executors.newCachedThreadPool();
        RunnableTask runnableTask = new RunnableTask();
        executor.execute(runnableTask);
        executor.shutdown();

二、Callable的使用场景

因为Callable的call方法提供返回值,所以当你需要知道任务执行的结果时,Callable是个不错的选择。Callable的实现很简单。

如下两个Callable任务分别返回false和0到520整数之和。

class BooleanCallableTask implements Callable<Boolean> {
    @Override
    public Boolean call() throws Exception {
        return false;
    }
}
class IntegerCallableTask implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 520; i++) {
            sum += i;
        }
        return sum;
    }
}

Callable任务通过线程池的submit方法提交。且submit方法返回Future对象,通过Future的get方法可以获得具体的计算结果。而且get是个阻塞的方法,如果任务未执行完,则一直等待。

        ExecutorService executor = Executors.newCachedThreadPool();
        IntegerCallableTask integerCallableTask = new IntegerCallableTask();
        Future<Integer> future = executor.submit(integerCallableTask);
        executor.shutdown();
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

三、关于Future和FutureTask

对于Calleble来说,Futurwww.chinasem.cne和FutureTask均可以用来获取任务执行结果,不过Future是个接口,FutureTask是Future的具体实现,而且FutureTask还间接实现了Runnable接口,也就是说FutureTask可以作为Runnable任务提交给线程池。

以下是个具体的实例演示FutureTask各种的使用方式。

   static class Task implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            System.out.println("子线程在进行计算");
            Thread.sleep(1000);
            int sum = 0;
            for (int i = 0; i < 10000; i++)
                sum += i;
            return sum;
        }
    }
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        //使用FutureTask
        Callable<Integer> task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        executor.submit(futureTask);
        //使用Future
//        Callable<Integer> call = new Task();
//        Future<Integer> future = executor.submit(call);
        executor.shutdown();
        System.out.println("主线程在执行任务");
        Thread.sleep(2000);
        try {
            System.out.println("task运行结果" + futureTask.get()); //future.get()
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("所有任务执行完毕");
    }

这个例子中使用Future和FutureTask都是一样的,都能获得相同的计算结果。

到此这篇关于Java中Runnable和Callable的区别和联系的文章就介绍到这了,更多相关Java Runnable和Callable的区别内容请搜索编www.chinasem.cn程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于Java中Runnable和Callable的区别和联系及使用场景的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:http://www.cppcns.com/ruanjian/java/704586.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1153809

相关文章

Java实现MD5加密的四种方式

《Java实现MD5加密的四种方式》MD5是一种广泛使用的哈希算法,其输出结果是一个128位的二进制数,通常以32位十六进制数的形式表示,MD5的底层实现涉及多个复杂的步骤和算法,本文给大家介绍了Ja... 目录MD5介绍Java 中实现 MD5 加密方式方法一:使用 MessageDigest方法二:使用

Java中的runnable 和 callable 区别解析

《Java中的runnable和callable区别解析》Runnable接口用于定义不需要返回结果的任务,而Callable接口可以返回结果并抛出异常,通常与Future结合使用,Runnab... 目录1. Runnable接口1.1 Runnable的定义1.2 Runnable的特点1.3 使用Ru

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

Java实现将Markdown转换为纯文本

《Java实现将Markdown转换为纯文本》这篇文章主要为大家详细介绍了两种在Java中实现Markdown转纯文本的主流方法,文中的示例代码讲解详细,大家可以根据需求选择适合的方案... 目录方法一:使用正则表达式(轻量级方案)方法二:使用 Flexmark-Java 库(专业方案)1. 添加依赖(Ma

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

使用国内镜像源优化pip install下载的方法步骤

《使用国内镜像源优化pipinstall下载的方法步骤》在Python开发中,pip是一个不可或缺的工具,用于安装和管理Python包,然而,由于默认的PyPI服务器位于国外,国内用户在安装依赖时可... 目录引言1. 为什么需要国内镜像源?2. 常用的国内镜像源3. 临时使用国内镜像源4. 永久配置国内镜

Spring Boot拦截器Interceptor与过滤器Filter详细教程(示例详解)

《SpringBoot拦截器Interceptor与过滤器Filter详细教程(示例详解)》本文详细介绍了SpringBoot中的拦截器(Interceptor)和过滤器(Filter),包括它们的... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程1. 概述1

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超