java 22 - 21 多线程之多线程的代码实现方式3

时间:2024-01-20 18:05:21

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、代码比较复杂,所以一般不用