Java 5 引入了多线程编程的一个新方法,不需要直接new Thread () 创建一个新的线程。只要创建一个 ExecutorService 的线程池,并将实现了 Callable 接口的任务(task)提交到线程池,就能得到带有回调结果的Future对象,通过操作Future得到结果,接下来,我们通过一个实例来学习这一部分的知识。
实例目的:通过两个线程,返回一个整型数组中的最大值。
首先,代码实现查找最大值的任务类:FindMaxTask
//导入util中Callable的包
import java.util.concurrent.Callable;
//实现Callable,这里的Integer表示回调的对象类型
//本例子返回的是整型数组中的最大值,所以为Integer类型
public class FindMaxTask implements Callable<Integer> {
//我们所需要的数据,一个整形数组,数组的开始,数组的结束
private int[] data;
private int start;
private int end;
//通过构造函数,初始化我们需要查的内容
public FindMaxTask(int[] data, int start, int end) {
this.data = data;
this.start = start;
this.end = end;
}
// 实现Callable中的方法,写入查找逻辑
@Override
public Integer call() throws Exception {
int max = Integer.MIN_VALUE;
for (int i = start; i < end; i++) {
if (data[i] > max)
max = data[i];
}
return max;
}
}
接下来,来实现创建线程池,以及提交任务,返回Future对象并对其进行操作:
//导入所需要的包
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MultithreadedMaxFinder {
//定义一个通过多线程查找最大值的静态函数
public static int max(int[] data){
//对传递进来的整形数组进行判断
if(data.length == 1)
return data[0];
else if(data.length == 0)
throw new IllegalAccessError();
//将数据分为两份
FindMaxTask fmt1 = new FindMaxTask(data, 0, data.length/2);
FindMaxTask fmt2 = new FindMaxTask(data, data.length/2, data.length);
//创建两个线程的线程池
ExecutorService service = Executors.newFixedThreadPool(2);
//向线程池提交Callable任务,并返回Future对象
Future<Integer> future1 = service.submit(fmt1);
Future<Integer> future2 = service.submit(fmt2);
try {
//关闭线程池,不影响 线程进行,通知线程池没有更多的线程了而已
service.shutdown();
//从上一个类,我们可以知道,FindMaxTask的call()方法返回的类型是int
//所以future对象的get()返回的结果也就是call的返回结果
//比较两个结果,返回数组的最大值
return Math.max(future1.get(), future2.get());
} catch (InterruptedException e) {
e.printStackTrace();
return 0;
} catch (ExecutionException e) {
e.printStackTrace();
return 0;
}
}
}
我们来测试一下
public class Test {
public static void main(String[] args) {
int[] data = {1,3,4,2,9,8,6};
System.out.println("data数组的最大是为:"+MultithreadedMaxFinder.max(data));
}
}
实验的结果:
data数组的最大是为:9
总结一下,这只是多线程处理的一下小小的例子,如果你的线程池提交的任务不需要回调,那么你可以实现 Runnable 接口而不用使用Callable接口,然后直接submit就可以了,不需要返回Future对象。最后是shutdown方法,方法的机制是告诉线程池对象,没有更多的任务需要提交了,等到执行完所有任务后,就关闭了。
更多的多线程知识,敬请关注更新,如有问题,以及博客错误,可以在下方留言共同讨论。