Java 5引入了多线程编程的一个新方法,通过隐藏细节可以更容易地处理回调。不再直接创建一个线程,通过创建一个ExecutorService,它会根据需要为你创建线程。可以向ExecutorService提交callable任务,对每个callable任务,会分别得到一个Future,之后可以向Future请求得到任务的结果。如果结果已经准备就绪,就会立即得到这个结果。如果还没有准备好,轮训线程会阻塞,直到结果准备就绪。这种做法的好处是可以创建很多不同的线程,然后按你需要的顺序得到你需要的答案。
Callable接口定义了一个call方法,可以返回任意的类型,以下为两个线程获取文件中最大值的例子
任务执行类
import java.util.concurrent.Callable;
public class findMaxTask implements Callable<Integer> {
private int start;
private int end;
private Integer[] data;
public findMaxTask(int start, int end, Integer[] data) {
this.start = start;
this.end = end;
this.data = data;
}
@Override
public Integer call() throws Exception {
int maxNum = Integer.MIN_VALUE;
//System.out.println(Thread.currentThread());
//Thread.sleep(3000);
for (int i = start; i < end; i ++) {
maxNum = Math.max(maxNum, data[i]);
}
return maxNum;
}
}
任务提交和结果获取类
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class maxFinder {
public static int getMax(Integer[] arr) throws ExecutionException, InterruptedException {
findMaxTask task1 = new findMaxTask(0, arr.length / 2, arr);
findMaxTask task2 = new findMaxTask(arr.length / 2, arr.length, arr);
ExecutorService service = Executors.newFixedThreadPool(2);
Future<Integer> ans1 = service.submit(task1);
Future<Integer> ans2 = service.submit(task2);
int maxNum1 = ans1.get();
int maxNum2 = ans2.get();
System.out.println("maxNum1 = " + maxNum1);
System.out.println("maxNum2 = " + maxNum2);
service.shutdown();
return Math.max(maxNum1, maxNum2);
}
}
测试类
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class Test {
public static List<Integer> list = new ArrayList<>();
public static void getInt(String str) {
String[] s = str.split(" ");
for (int i = 0; i < s.length; i ++) {
list.add(Integer.parseInt(s[i]));
}
}
public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
FileReader fr = new FileReader("data.txt");
BufferedReader br = new BufferedReader(fr);
String line = null;
while((line = br.readLine()) != null) {
Test.getInt(line);
}
br.close();
Integer[] arr = list.toArray(new Integer[list.size()]);
System.out.println(maxFinder.getMax(arr));
}
}