Callable与Future

Callable与Runnable类似,但是有返回值,其接口是一个参数化的类型,只有一个call方法(类似Runnable中的run方法)
Future保存异步计算的结果,可以启动一个计算(callable),将Future对象交付给线程即可。当计算结束时,通过get方法获取计算结果。若计算未完成,则调用被阻塞,直到完成。可以通过isDone方法判断计算是否完成。
FutureTask包装器,可将Callable转换为Future和Runnable,同时实现二者的接口。

Callable_1 callable1=new Callable_1();
FutureTask<Integer> result=new FutureTask<>(callable1);
new Thread(result).start();

result.get();

eg1:通过callable和future打印一组数据

package com.lmr.thread;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class Callable_Future_1 {

    public static void main(String[] args) {

        Callable_1 callable1=new Callable_1();
        FutureTask<Integer> result=new FutureTask<>(callable1);
        new Thread(result).start();//启动result的FutureTask对象,去执行callable1的call方法

        System.out.println("main thread is running");

        try {
            System.out.println("result: "+result.get());//获取结果
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("main thread is ending");

    }

}

public class Callable_1 implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        // TODO Auto-generated method stub

        System.out.println("callable is runing");

        int sum=0;
        for(int i=0;i<10;i++){

            Thread.sleep(1000);
            sum+=i;
            System.out.println(i+" - "+sum);//每隔1秒打印数据

        }

        return sum;
    }

}

通过打印的结果,我们发现到程序跑到get方法时,并没有获取到结果,而是等callable1的call方法执行完毕后,才会打印结果

callable is runing
main thread is running
0 - 0
1 - 1
2 - 3
3 - 6
4 - 10
5 - 15
6 - 21
7 - 28
8 - 36
9 - 45
result: 45
main thread is ending

eg2:搜索指定目录下所有文件内容,计算关键字的个数

package com.lmr.thread;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class Callable_Future_2 {

    public static void main(String[] args) {
        String directory="E:\\Java_Swing\\src\\com\\swing";
        String keyword="JPanel";

        MatchCount counter=new MatchCount(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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }
}

class MatchCount implements Callable<Integer>{

    private File directory;
    private String keyword;
    private int count;//关键字数目

    public MatchCount(File directory,String keyword) {
        // TODO Auto-generated constructor stub
        this.directory=directory;
        this.keyword=keyword;
    }

    @Override
    public Integer call() throws Exception {
        // TODO Auto-generated method stub

        count=0;
        try{
            File[] files=directory.listFiles();
            List<Future<Integer>> results=new ArrayList<>();//Future对象List

            for(File file:files){
                if(file.isDirectory()){
                    MatchCount counter=new MatchCount(file, keyword);//递归遍历
                    FutureTask<Integer> task=new FutureTask<>(counter);
                    results.add(task);
                    Thread t=new Thread(task);
                    t.start();
                }
                else{
                    if(search(file)){//若是文件,则去计算数目
                        count+=searchsum(file);
                    }
                }
            }
            for(Future<Integer> result:results){//当该目录下所有文件的Future计算完后,累加数目
                count+=result.get();
            }
        }
        catch (Exception e) {
            // TODO: handle exception
        }
        return count;
    }

    public boolean search(File file){//判断文件是否有关键字
        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) {
            // TODO: handle exception
            return false;
        }
    }

    public int searchsum(File file) throws FileNotFoundException {//关键字计数
        Scanner in = new Scanner(file);
        int found = 0;
        while (in.hasNextLine()) {
            String line = in.nextLine();
            while (line.contains(keyword)) {
                System.out.println(line);
                line=line.substring(line.indexOf(keyword)+keyword.length());
                found++;
            }
        }
        return found;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值