java多线程--Callable、Future
Java 实现多线程的二种方式:
方式一:继承Thread类
方式二:实现Runnable接口
示例代码如下:
// 方式一:继承Thread类 Thread thread01 = new Thread() { @Override public void run() { System.out.println("线程二:hello"); } }; thread01.start(); // 方式二:实现Runnable接口 Thread thread02 = new Thread(() -> System.out.println("线程三:hello")); thread02.start();
这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。
下面就来了解下Callable与Runnable
Callable 与 Runnable
Runnable接口,来自java.lang.Runnable,只声明了run()方法
@FunctionalInterface public interface Runnable { public abstract void run(); }
由于run()方法返回值为void类型,所以在执行完任务之后无法返回任何结果。
Callable接口,来自java.util.concurrent.Callable<V>,也只声明了一个call()方法
@FunctionalInterface public interface Callable<V> { V call() throws Exception; }
可以看到,这是一个泛型接口,call()函数返回的类型就是传递进来的V类型。
那么怎么使用Callable呢?一般情况下是配合ExecutorService来使用的
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
接下来了解下Future
Future
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
Future类位于java.util.concurrent包下,它是一个接口:
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
boolean cancel(boolean mayInterruptRunning):试图取消该Future关联的Callable任务。
V get():返回Callable里call()方法的返回值。该方法会导致程序阻塞,必须等到子线程结束时才能得到返回值。
V get(long timeout,TimeUnit unit):返回Callable里call()方法的返回值。该方法最多让程序等待timeout和unit指定的时间,到达指定时间后还没有得到返回值,将会抛出TimeoutException异常。
boolean isCancelled():如果Callable任务在正常完成前被取消,则返回true。
boolean isDone():如果Callable任务已经完成,则返回true。
也就是说Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask

FutureTask类实现了RunnableFuture接口。
RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
FutureTask提供了2个构造器:
public FutureTask(Callable<V> callable) {} public FutureTask(Runnable runnable, V result) {}
事实上,FutureTask是Future接口的一个唯一实现类。
示例:
了解了这些之后,下面是两个Callable的示例
示例一:Thread.start()启动线程
public static void main(String[] args) { // 获取线程的返回值 AtomicInteger atomicInteger = new AtomicInteger(0); FutureTask futureTask = new FutureTask(() -> { atomicInteger.set(atomicInteger.get() + 1); return atomicInteger.get(); }); Thread thread = new Thread(futureTask); thread.start(); try { System.out.println( futureTask.get() ); // 1 } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
示例二:通过ExecutorService执行线程
public static void main(String[] args) { // 通过ExecutorService执行线程 AtomicInteger atomicInteger = new AtomicInteger(); ExecutorService executorService = Executors.newSingleThreadExecutor(); Future submit = executorService.submit(() -> { atomicInteger.set(atomicInteger.get() + 1); return atomicInteger.get(); }); try { System.out.println( submit.get() ); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!