Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式: 实现 Callable 接口。

Callable 接口类似于 Runnable,但是 Runnable 不会返回结果,并且无法抛出经过检查的异常,而 Callable 依赖 FutureTask 类获取返回结果。

没有使用线程池:

代码演示:

public class CallableTest {
    public static void main(String[] args) throws Exception {
        
        MyThread mt = new MyThread();
        
        FutureTask<Integer> result = new FutureTask<Integer>(mt);
        
        new Thread(result).start();
        
        // 获取运算结果是同步过程,即 call 方法执行完成,才能获取结果
        Integer sum = result.get();
        
        System.out.println(sum);
    }
}
class MyThread implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        
        return sum;
    }
    
}

单个线程池: 使用ExecutorService、Callable、Future实现有返回结果的线程

ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

public class MyCallable implements Callable<String> {

    /**
     * 实现call方法,接口中抛出异常。因为子类不可以比父类干更多的坏事,所以子类可以不抛出异常
     */
    @Override
    public String call() {
        System.out.println(Thread.currentThread().getName() + "   执行callable的call方法");
        return "result";
    }

    public static void main(String[] args) {
        test1();
    }

    /**
     * 单个线程
     */
    public static void test1() {
        // 1.创建固定大小的线程池
        ExecutorService es = Executors.newFixedThreadPool(1);
        // 2.提交线程任务,用Future接口接受返回的实现类
        Future<String> future = es.submit(new MyCallable());
        // 3.关闭线程池
        es.shutdown();
        // 4.调用future.get()获取callable执行完成的返回结果
        String result;
        try {
            result = future.get();
            System.out.println(Thread.currentThread().getName() + "\t" + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

结果:

结果:

pool-1-thread-1 执行callable的call方法
main result

多个线程的执行返回结果: 

public class MyCallable implements Callable<String> {

    /**
     * 实现call方法,接口中抛出异常。因为子类不可以比父类干更多的坏事,所以子类可以不抛出异常
     */
    @Override
    public String call() {
        System.out.println(Thread.currentThread().getName() + "   执行callable的call方法");
        return "result";
    }

    public static void main(String[] args) {
        test2();
    }
/**
     * 多个线程
     */
    public static void test2() {
        // 1.创建固定大小的线程池(5个)
        int threadNum = 5;
        ExecutorService es = Executors.newFixedThreadPool(threadNum);
        // 2.提交线程任务,用Future接口接受返回的实现类
        List<Future<String>> futures = new ArrayList<Future<String>>(threadNum);
        for (int i = 0; i < threadNum; i++) {
            Future<String> future = es.submit(new MyCallable());
            futures.add(future);
        }
        // 3.关闭线程池
        es.shutdown();
        // 4.调用future.get()获取callable执行完成的返回结果
        for (Future<String> future : futures) {
            try {
                String result = future.get();
                System.out.println(Thread.currentThread().getName() + "\t" + result);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    }

}
结果:

pool-1-thread-1 执行callable的call方法
pool-1-thread-2 执行callable的call方法
pool-1-thread-4 执行callable的call方法
pool-1-thread-3 执行callable的call方法
main result
pool-1-thread-5 执行callable的call方法
main result
main result
main result
main result

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐