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

时间:2023-03-09 05:25:27
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方法时,会阻塞当前线程,等待任务返回值