在Java中,从线程返回数据主要有两种方法:使用`Callable`接口和`Future`类,以及使用共享变量或集合。由于你要求的是“简洁且高效”的方法,这里我将重点介绍第一种方法,因为它提供了直接返回结果的机制,且易于理解和使用。
### 方法一:使用`Callable`和`Future`
`Callable`接口类似于`Runnable`,但它可以返回一个结果,并且可以声明抛出的异常。`Future`表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
**示例代码**:
import java.util.concurrent.*;
public class CallableExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建一个ExecutorService
ExecutorService executor = Executors.newCachedThreadPool();
// 提交Callable任务到线程池
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// 模拟耗时计算
Thread.sleep(1000);
return 123; // 返回计算结果
}
});
// 等待任务完成并获取结果
Integer result = future.get(); // 这会阻塞,直到任务完成
System.out.println("Result from thread: " + result);
// 关闭ExecutorService
executor.shutdown();
}
}
在这个例子中,我们创建了一个`ExecutorService`,并向它提交了一个`Callable`任务。`Callable`任务执行完毕后,我们通过`Future.get()`方法获取结果。需要注意的是,`Future.get()`会阻塞当前线程,直到`Callable`任务执行完成。
这种方法简洁且高效,因为它允许直接从线程获取结果,并且处理异常也更为方便(`Callable`可以声明抛出异常,而`Runnable`不可以)。
### 方法二:使用共享变量或集合(不推荐为“简洁且高效”的首选)
虽然可以使用共享变量或集合来从线程返回数据,但这种方法通常需要额外的同步控制来确保数据的一致性和线程安全,这会使代码变得复杂且容易出错。因此,在追求简洁和高效时,通常不推荐使用这种方法。
以上是使用`Callable`和`Future`从Java线程返回数据的推荐方法。