Callable及Future

2024-06-24 08:18
文章标签 callable future

本文主要是介绍Callable及Future,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.Runnable

Runnable是个接口,使用很简单:
1. 实现该接口并重写run方法
2. 利用该类的对象创建线程
3. 线程启动时就会自动调用该对象的run方法
通常在开发中结合ExecutorService使用,将任务的提交与任务的执行解耦开,同时也能更好地利用Executor提供的各种特性
复制代码
ExecutorService executor = Executors.newCachedThreadPool();executor.submit(new Runnable() { public void run() {//TODO
                        }});
executor.shutdown();
复制代码
相对于继承Thread来创建线程方式,使用Runnable可以让你的实现类同时实现多个接口,而相对于Callable及Future,Runnable方法并不返回任务执行结果且不能抛出异常
2.Callable
与Runnable不同的是,Callable是个泛型参数化接口,并能返回线程的执行结果,且能在无法正常计算时抛出异常
public interface Callable<V> {V call() throws Exception;
}
1. Callable并不像Runnable那样通过Thread的start方法就能启动实现类的run方法,所以它通常利用ExecutorService的submit方法去启动call方法自执行任务,而ExecutorService的submit又返回一个Future类型的结果,因此Callable通常也与Future一起使用
 ExecutorService pool = Executors.newCachedThreadPool();Future<String> future = pool.submit(new Callable{public void call(){//TODO
           }});
或者利用FutureTask封装Callable再由Thread去启动(少用)
复制代码
 FutureTask<String> task = new FutureTask(new Callable{public void call(){//TODO
        }});Thead thread = new Thread(task);thread.start();
复制代码
2. 通过Executors.callbale(Runnable task,T result)可以执行Runnable并返回"结果",但是这个结果并不是Runnable的执行结果(Runnable的run方法是void类型),而是执行者预定义的结果,这点可以从其实现原理RunnableAdpter源码看出
复制代码
public static <T> Callable<T> callable(Runnable task, T result) {if (task == null)throw new NullPointerException();return new RunnableAdapter<T>(task, result);//通过RunnableAdapter实现
}static final class RunnableAdapter<T> implements Callable<T> {final Runnable task;final T result;RunnableAdapter(Runnable task, T result) {this.task = task;this.result = result;}public T call() {task.run();return result; //将传入的结果的直接返回}}
复制代码
Runnable与Callable不同点:
1. Runnable不返回任务执行结果,Callable可返回任务执行结果
2. Callable在任务无法计算结果时抛出异常,而Runnable不能
3. Runnable任务可直接由Thread的start方法或ExecutorService的submit方法去执行
3.Future
Future保存异步计算的结果,可以在我们执行任务时去做其他工作,并提供了以下几个方法
* cancel(boolean mayInterruptIfRunning):试图取消执行的任务,参数为true时直接中断正在执行的任务,否则直到当前任务执行完成,成功取消后返回true,否则返回false
* isCancel():判断任务是否在正常执行完前被取消的,如果是则返回true
* isDone():判断任务是否已完成
* get():等待计算结果的返回,如果计算被取消了则抛出
* get(long timeout,TimeUtil unit):设定计算结果的返回时间,如果在规定时间内没有返回计算结果则抛出TimeOutException
使用Future的好处:
1. 获取任务的结果,判断任务是否完成,中断任务
1. Future的get方法很好的替代的了Thread.join或Thread,join(long millis)
2. Future的get方法可以判断程序代码(任务)的执行是否超时,如:
 try{future.get(60,TimeUtil.SECOND);}catch(TimeoutException timeout){log4j.log("任务越野,将被取消!!");future.cancel();}
4.FutureTask
FutureTask实现了RunnableFuture接口,提供了即可以使用Runnable来执行任务,又可以使用Future执行任务并取得结果的构造器,所以可以利用FutureTask去封装Runnable或Callable对象,之后再submit任务
 FutureTask(Callable<V> callable)  FutureTask(Runnable runnable, V result)

5.应用

查找包含某关键字的文件个数:每个文件启动一个线程去查找关键字
复制代码
public class FileSearchTask {public static void main(String[] args) throws ExecutionException, InterruptedException {String path = args[0];String keyword = args[1];int c = 0;File[] files = new File(path).listFiles();ArrayList<Future<Integer>> rs = new ArrayList<>();for(File file: files){  //每个文件启动一个task去查找MatchCount count = new MatchCount();count.file = file;count.keyword = keyword;FutureTask<Integer> task = new FutureTask(count);rs.add(task); //将任务返回的结果添加到集合中Thread thread = new Thread(task);thread.start();}for(Future<Integer> f: rs){c += f.get(); //迭代返回结果并累加
        }System.out.println("包含关键字的总文件数为:" + c);}
}class  MatchCount implements Callable<Integer>{public File file;public String keyword;private  Integer count = 0;public Integer call() throws Exception {   //call封装线程所需做的任务if(search(file))count ++;return count;}public boolean search(File file){boolean founded = false;try(Scanner scanner = new Scanner(new FileInputStream(file))){while(!founded && scanner.hasNextLine()){if (scanner.nextLine().contains(keyword))founded = true;}} catch (FileNotFoundException e) {e.printStackTrace();}return  founded;}
}
复制代码

这篇关于Callable及Future的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089601

相关文章

【硬刚Java并发】JUC基础(五):实现 Callable 接口

本文是对《【硬刚大数据之学习路线篇】从零到大数据专家的学习指南(全面升级版)》的Java并发部分补充。 1 Callable 接口 Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式:Callable 接口 Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果

Java并发编程:Callable和Future使用

在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。我们一般只能采用共享变量或共享存储区以及线程通信的方式实现获得任务结果的目的。 不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作。Callable用来执行任务,产生结果,而Future用来获得结果。 C

std::future和std::promise详解(原理、应用、源码)

在编程实践中,我们常常需要使用异步调用。通过异步调用,我们可以将一些耗时、阻塞的任务交给其他线程来执行,从而保证当前线程的快速响应能力。还有一些场景可以通过将一个任务,分成多个部分然后将这部分交给多个线程来进行并发执行,从而完成任务的快速计算执行,提高应用性能。这里就需要用到异步调用的概念 异步调用,就是当前线程将一个任务交给另外一个线程来进行执行,当前线程会接着执行当前任务,不需要等待这个交付

Future 原理模拟

大家已经知道Future可以异步返回结果,但是其中的原理 却并不是所有人都懂  今天偶然看见了一段模拟原理的代码 就记录一下 首先大致介绍下其中的原理 : 在客户端请求的时候,直接返回客户端需要的数据(此数据不一定完整,只是简单的一点不耗时的操作),但是客户端并不一定马上使用所有的信息,此时就有了时间去完善客户需要的信息  大致原理如此 说到底就是一个简单的异步操作,下面贴上源码 并做简单的介绍

Java 通过Future来对任务进行取消

本节我们将通过Java中的Future实现对于提交的任务进行取消。ExecutorService.submit将返回一个Future来描述任务,Future拥有一个cancel方法,该方法带有一个boolean类型的参数mayInterruptIfRunning,表示取消操作是否成功(这个参数只是表示任务是否能够接收中断,而不是表示任务是否能检测并处理中断)。如果mayInterrup

【Python报错已解决】`TypeError: ‘numpy.ndarray‘ object is not callable`

引言: 在编程中,你是否遇到过尝试调用一个Numpy数组对象时出现了TypeError: 'numpy.ndarray' object is not callable的报错?这个问题通常是由于误将Numpy数组当成了一个函数来调用。接下来,我们将分析这个问题并提供解决方案。 一、问题描述: 1.1 报错示例: import numpy as np# 创建一个Numpy数组arra

论文笔记:Estimating future human trajectories from sparse time series data

sigspatial 2023 humob竞赛paper hiimryo816/humob2023-MOBB (github.com) 1 数据集分析 这里只分享了HuMob数据集1的内容 1.1 假日分析 对HuMob数据集#1地理数据的方差分析显示了非工作日的模式 在某些天的y坐标方差中有显著的峰值,这是非工作日的象征【x坐标有相似的模式】 ——>识别了任务1数据集中最有可能是

Java源码分析----Future

一般使用多线程操作的时候会使用Thread+Runnable进行处理,但是这种方式中,Runnable是没有返回值的,假设我们需要获取Runnable的返回值,可能需要如下特殊处理,伪代码如下 String returnValue1 = "";String returnValue2 = "";CountDownLatch cdl = ....new Thread(()->{// xxxx操

java多线程-使用Future获得多线程的返回值

我们在多线程中很多时候会需要获得线程的返回值,但是多线程又不像普通方法一样,可以直接获得返回值,那么我们应该怎么获得返回值呢?   一、使用Future获得Callable的返回值 import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.conc

Callable Future Executor

一般通过继承Thread还有实现Runnable,都不可以有返回值,不可以声明检查异常。 Callable和Future,通过ExecutorService的submit方法执行Callable,并返回给Future,这里返回值只有一个,ExecutorService继承自Executor,通过使用Executor执行器来操作。 public class CallableAndFuture {