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