Java多线程——Callable与Future

二月份回家过年了,家里没网,所以博客也停了一段时间,上班已经一周了,总的来说还是比较忙吧!周末还是把没总结完的知识点总结一下,方便日后翻阅!

Callable与Future

Runnable封装一个异步运行的任务,可以把它想象成一个没有参数和返回值的异步方法。Callable与Runnable类似,但是有返回值。Callable接口是一个参数化的类型,只有一个方法call。

public interface Callable<V>{
    V call() throws Exception;
}

类型参数是返回值的类型。

Future保存异步计算的结果。可以启动一个计算,将Future对象交给某个线程,然后忘得它。Future对象的所有者在结果计算好之后就可以捕获它。

Future接口有以下方法:

public interface Future<V>{
    v get() throws ...;
    v get(long timeout, TimeUnit unit) throws ...;
    void calcel(boolean mayInterrupt);
    boolean isCancelled();
    boolean isDone();
}

第一个get方法的调用被阻塞,直到计算完成。如果在计算完成之前,第二个方法的调用超时,抛出一个TimeoutException异常。如果运行该计算的线程被中断,两个方法都将抛出InterruptedException。如果计算完成,那个get方法立即返回。

如果计算还在进行,isDone方法返回false;如果完成了,则返回true。

可以用cancel方法取消该计算。如果计算还没有开始,它被取消且不再开始。如果计算处于运行之中,那么如果mayInterrupt参数为true,它就被中断。

FutureTask包装器是一种很便利的机制,可将Callable转化成Future和Runnable,它同时实现二者的接口。

我们使用Future对上一篇博客中的例子进行修改,然后测试一下。

MacthCounter类:

/**
 * @author xzzhao
 */
public class MacthCounter implements Callable<Integer> {

    private final File   directory;
    private final String keyword;
    private int          count;

    public MacthCounter(File directory, String keyword) {
        super();
        this.directory = directory;
        this.keyword = keyword;
    }

    @Override
    public Integer call() throws Exception {
        count = 0;
        File[] files = directory.listFiles();
        List<Future<Integer>> results = new ArrayList<>();
        for (File file : files) {
            if (file.isDirectory()) {
                MacthCounter counter = new MacthCounter(file, keyword);
                FutureTask<Integer> task = new FutureTask<>(counter);
                results.add(task);
                Thread t = new Thread(task);
                t.start();
            } else {
                if (search(file)) {
                    count++;
                }
            }
        }
        for (Future<Integer> result : results) {
            count += result.get();
        }
        return count;
    }

    public boolean search(File file) {
        try {
            try (Scanner in = new Scanner(file)) {
                boolean found = false;
                while (!found && in.hasNextLine()) {
                    String line = in.nextLine();
                    if (line.contains(keyword)) {
                        found = true;
                    }
                }
                return found;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

MacthCounter 类:

/**
 * @author xzzhao
 */
public class FutureTest {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入根目录 :");
        String directory = in.nextLine();
        System.out.println("请输入关键字 :");
        String keyword = in.nextLine();

        MacthCounter counter = new MacthCounter(new File(directory), keyword);
        FutureTask<Integer> task = new FutureTask<>(counter);
        Thread t = new Thread(task);
        t.start();
        try {
            System.out.println("匹配到的文档数:" + task.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
时间: 2024-12-07 13:25:00

Java多线程——Callable与Future的相关文章

Java多线程 - Callable和Future

已知的创建多线程的方法有继承Tread类和实现Runnable方法.此外Java还提供了Callable接口,Callable接口也提供了一个call()方法来做为线程执行体.但是call()方法与run()方法有些不同: call()方法可以有返回值 call()方法可以抛出异常 不过Java不允许Callable对象直接作为Thread的target.而且call()方法还有一个返回值--call()方法并不是直接调用,他是做为线程执行体被调用的.Java提供了Future接口来代表Call

Java多线程Callable和Future类详解

     public interface Callable<V>    返回结果并且可能抛出异常的任务.实现者定义了一个不带任何参数的叫做 call 的方法      public interface Future<V>      Future 表示异步计算的结果.计算完成后只能使用 get 方法来获取结果 1.线程处理返回结果 一般开发中,使用多线程,最常见的就是:1.实现Runnable接口:2.继承Thread类. 但是run方法是没有返回结果,很难满足我们的需求.这时,常

java多线程编程之Future/FutureTask和Callable

有这样一种场景,用多线程发送数据到某个服务器,需要知道各个线程是否都发送成功,等所有线程都发送完成才能继续下一轮计算和发送.如果用传统的多线程方式,就需要启动多个线程,然后在每个线程中分别发送数据,外部通过某种方式等待各个线程全部都发送完成,再进行后面的计算等流程.这种实现方式的代码会比较臃肿,在java中提供了一种Callable+Future的方法,可以将异步的多线程调用变为同步方式. Callable 在java的多线程编程中,有Thread和Runnable两种方式来新建线程,其中Run

java多线程Callable,Future,FutureTask

我们平时接触到的多线程Thread,Runnable,这两种方式不能返回线程执行后的结果. Callable和Future,前者产生结果,后者拿到结果. Callable和Future 推荐一篇不错的博客:http://blog.csdn.net/ghsau/article/details/7451464 public class GreyStartServlet extends HttpServlet { @Override public void init() throws ServletE

Java多线程编程中Future模式的详解&lt;转&gt;

Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Future模式,关于其他多线程设计模式的地址如下:关于其他多线程设计模式的地址如下:关于Master-Worker模式的详解: Java多线程编程中Master-Worker模式的详解关于Guarded Suspeionsion模式的详解: Java多线程编程中Guarded Suspeionsion模式

Java并发——Callable和Future

Callable和Future Executor框架将工作单元划分为任务,即任务是逻辑上的工作单元,而线程是任务异步执行的机制.Runnable是任务的一个抽象,并且理想状态下任务是独立的执行,但是Runnable的run( )不能返回一个结果或者抛出一个受检查的异常,这与我们有些实际任务是不相符的.在通过线程或者executor执行Runnable任务中,不仅仅是不能返回任务的执行结果,有时我们希望可以控制某个任务,或取消或终止,但在executor中一旦提交任务,我们将很难单一的控制任务的生

Java - 多线程Callable、Executors、Future

http://blog.csdn.net/pipisorry/article/details/44341579 Introduction Callable接口代表一段能够调用并返回结果的代码; Future接口表示异步任务.是还没有完毕的任务给出的未来结果. 所以Callable用于产生结果,Future用于获取结果. Callable接口:Java 5在concurrency包中引入了java.util.concurrent.Callable 接口.它和Runnable接口非常类似,但它能够返

Java 多线程中的Future

我们先来了解一下什么是Future Future模式是多线程开发中非常常见的一种设计模式.它的核心思想是异步调用.当我们需要执行一段复杂业务代码,可能要的时间很长,我们也许不是马上需要结果,那么这时候就可以把这个代码托管给Future让他慢慢处理, 我们继续做其他事情,等我什么时候需要用到的时候再来调这个结果. 可能有人会问那为什么不用Thread呢?很显然run方法是没有返回值的这时候就要用到Future. Future如何使用能够获取子线程运行的结果呢?在这里顺便提一下Callable接口,

Java利用Callable、Future进行并行计算求和

内容:在Java中利用Callable进行带返回结果的线程计算,利用Future表示异步计算的结果,分别计算不同范围的Long求和,类似的思想还能够借鉴到需要大量计算的地方. public class Sums { public static class Sum implements Callable<Long> { private final Long from; private final Long to; public Sum(long from, long to) { this.fro