随笔 - 832  文章 - 2  评论 - 31  阅读 - 167万

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();
        }
    }
复制代码

 





posted on   小破孩楼主  阅读(240)  评论(0编辑  收藏  举报
编辑推荐:
· 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代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示