Java Callable接口——有返回值的线程

实际开发过程中,我们常常需要等待一批线程都返回结果后,才能继续执行。《线程等待——CountDownLatch使用》中我们介绍了CountDownLatch的使用,通过使用CountDownLatch,可以实现线程等待。

JDK 1.8实现了一种更好的方式,实现线程等待与获取线程返回值,那就是Callable接口,下面我们来看看具体代码。

package com.coshaho.learn;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.kafka.common.group.Time;

public class CallableLearn
{
    public static void main(String[] args) throws InterruptedException, ExecutionException
    {
        long start = System.currentTimeMillis();
        MyCallableTask task1 = new MyCallableTask();
        MyCallableTask task2 = new MyCallableTask();
        MyCallableTask task3 = new MyCallableTask();
        
        // 使用线程池submit方法,可以获取返回值
        Future<String> future1 = FIXED_THREADPOOL.submit(task1);
        Future<String> future2 = FIXED_THREADPOOL.submit(task2);
        Future<String> future3 = FIXED_THREADPOOL.submit(task3);
        long end = System.currentTimeMillis();
        
        // 任务提交不会阻塞
        System.out.println("Submit task cost " + (end - start) + "ms.");
        
        System.out.println("Task1: " + future1.get());
        System.out.println("Task2: " + future2.get());
        System.out.println("Task3: " + future3.get());
        
        // Future.get方法等待线程返回值
        System.out.println("Get task return value cost " + (System.currentTimeMillis() - end) + "ms.");
    }
    
    // 大小为3的线程池
    public final static ExecutorService FIXED_THREADPOOL = Executors.newFixedThreadPool(3);
    
    public static class MyCallableTask implements Callable<String>
    {
        // 睡i秒并返回信息
        @Override
        public String call() throws Exception
        {
            Random random = new Random();
            int i = random.nextInt(10) * 1000;
            Time.sleep(i);
            return "Sleep " + i + "ms.";
        }
        
    }

}


结果

Submit task cost 3ms.
Task1: Sleep 5000ms.
Task2: Sleep 8000ms.
Task3: Sleep 8000ms.
Get task return value cost 8659ms.

 三个关键点

1、 线程需要实现Callable接口

2、 线程池采用submit方法提交任务,可以获取返回值Future

3、 使用Future.get方法时,会阻塞当前线程,等待任务返回值

posted @ 2017-09-02 10:33  coshaho  阅读(862)  评论(0编辑  收藏  举报