JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法
A、public static ExecutorService newCachedThreadPool()
B、public static ExecutorService newFixedThreadPool(int nThreads)
C、public static ExecutorService newSingleThreadExecutor()
这些方法的返回值是ExecutorService对象
该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的线程。
上一次实现的是执行Runnable对象的,这次实现下Callable对象的
注意:Callable:是带泛型的接口。这里指定的泛型其实是call()方法的返回值类型。
例子:多线程同时对不同的数段进行求和
首先创建一个类来继承Callable接口
public class MyCallable implements Callable<Integer> { // 由于这里需要2个数,开始和结束的数值。
// 所以创建对象,并且写构造方法接收数值
private int start;
private int end; public MyCallable(int start, int end) {
this.start = start;
this.end = end;
}
int sum = 0;
public Integer call() throws Exception {
for (int x = start; x <= end; x++) { sum += x;
}
return sum;
} }
再创建测试类:
public class CallableDemo { public static void main(String[] args) throws InterruptedException,
ExecutionException { // 创建线程池对象
ExecutorService pool = Executors.newFixedThreadPool(3); // 调用方法
// Future<?> submit(Runnable task)
// <T> Future<T> submit(Callable<T> task)
// 这里需要使用泛型来接收结果,由于Callable中的泛型就是返回类型,所以是用Future<T>
Future<Integer> f1 = pool.submit(new MyCallable(1, 100));
Future<Integer> f2 = pool.submit(new MyCallable(100, 200));
Future<Integer> f3 = pool.submit(new MyCallable(1, 200)); // 由于Mycallable类返回了计算的结果,所以这里需要一个方法来接收这个结果
// V get(); 这里需要抛异常
Integer n1 = f1.get();
Integer n2 = f2.get();
Integer n3 = f3.get(); System.out.println(n1);
System.out.println(n2);
System.out.println(n3); //关闭线程
pool.shutdown(); }
}
这种方式的好处是:
A、可以有返回值
B、可以抛出异常
弊端是:
A、代码比较复杂,所以一般不用