Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。
Callable的接口定义如下;
public interface Callable<V> {
V call() throws Exception;
}
Callable和Runnable的区别如下:
I Callable定义的方法是call,而Runnable定义的方法是run。
II Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。
III Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。
Future 介绍
Future表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。Future的cancel方法可以取消任务的执行,它有一布尔参数,参数为 true 表示立即中断任务的执行,参数为 false 表示允许正在运行的任务运行完成。Future的 get 方法等待计算完成,获取计算结果
例子:
1 import java.io.*; 2 import java.util.*; 3 import java.util.concurrent.*; 4 5 6 public class FutureTest 7 { 8 public static void main(String[] args) 9 { 10 Scanner in = new Scanner(System.in); 11 System.out.print("Enter base directory (e.g. /usr/local/jdk5.0/src): "); 12 String directory = in.nextLine(); 13 System.out.print("Enter keyword (e.g. volatile): "); 14 String keyword = in.nextLine(); 15 16 MatchCounter counter = new MatchCounter(new File(directory), keyword); 17 FutureTask<Integer> task = new FutureTask<Integer>(counter); 18 Thread t = new Thread(task); 19 t.start(); 20 try 21 { 22 System.out.println(task.get() + " matching files."); 23 } 24 catch (ExecutionException e) 25 { 26 e.printStackTrace(); 27 } 28 catch (InterruptedException e) {} 29 } 30 } 31 32 33 /** 34 This task counts the files in a directory and its subdirectories that contain a given keyword. 35 */ 36 class MatchCounter implements Callable<Integer> 37 { 38 /** 39 Constructs a MatchCounter. 40 @param directory the directory in which to start the search 41 @param keyword the keyword to look for 42 */ 43 public MatchCounter(File directory, String keyword) 44 { 45 this.directory = directory; 46 this.keyword = keyword; 47 } 48 49 50 public Integer call() 51 { 52 count = 0; 53 try 54 { 55 File[] files = directory.listFiles(); 56 ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>(); 57 58 59 for (File file : files) 60 if (file.isDirectory()) 61 { 62 MatchCounter counter = new MatchCounter(file, keyword); 63 FutureTask<Integer> task = new FutureTask<Integer>(counter); 64 results.add(task); 65 Thread t = new Thread(task); 66 t.start(); 67 } 68 else 69 { 70 if (search(file)) count++; 71 } 72 73 for (Future<Integer> result : results) 74 try 75 { 76 count += result.get(); 77 } 78 catch (ExecutionException e) 79 { 80 e.printStackTrace(); 81 } 82 } 83 catch (InterruptedException e) {} 84 return count; 85 } 86 87 88 /** 89 Searches a file for a given keyword. 90 @param file the file to search 91 @return true if the keyword is contained in the file 92 */ 93 public boolean search(File file) 94 { 95 try 96 { 97 Scanner in = new Scanner(new FileInputStream(file)); 98 boolean found = false; 99 while (!found && in.hasNextLine()) 100 { 101 String line = in.nextLine(); 102 if (line.contains(keyword)) found = true; 103 } 104 in.close(); 105 return found; 106 } 107 catch (IOException e) 108 { 109 return false; 110 } 111 } 112 113 114 private File directory; 115 private String keyword; 116 private int count; 117 } 118 119 120