线程创建------使用Callable和Future

Start
从Java5开始,Java提供了Callable接口(也是函数式接口),该接口提供了一个call()方法可以作为线程执行体,相较于run()方法,call()方法功能更强大:

(1)call()方法可以有返回值。
(2)call()方法可以声明抛出异常。
在这里插入图片描述

由于Callable接口是Java5新增的接口,而且它不是Runnable接口的子接口,所以就不能作为Thread的target。而且call()方法还有一个返回值,如何获取这个返回值呢?Java5提供了Future接口来代表Callable接口里call()方法的返回值,并为Future接口提供了一个FutureTask实现类,该实现类实现了Future接口,,同时也实现了Runnable接口(可以作为Thread类的target了)

Future 接口定义了如下几个公共方法来控制它关联的Callable任务:
(1)boolean cancel(boolean mayInterruptIfRunning):试图取消该Future里关联的Callable任务。
(2)V get():返回Callable任务里call()方法的返回值。调用该方法将导致程序阻塞,必须等到子线程结束后才会得到返回值。
(3)V get(long timeout,TimeUnit unit):返回Callable任务里call()方法的返回值。该方法让程序最多阻塞timeout和unit指定的时间。如果经过指定时间Callable任务依然没有返回值,将会抛出TimeoutException异常。
(4)boolean isCancelled():如果在Callable任务正常完成前被取消,则返回true。
(5)boolean isDone():如果Callable任务完成,返回true。

How
创建并启动有返回值的线程的步骤:

(1)创建Callable接口的实现类,并重写该类的call()方法,该call()方法将作为线程执行体,且该call()方法有返回值,再创建Callable实现类的实例。从Java8开始,可以直接使用Lambda表达式创建Callable对象。
(2)使用FutureTask类包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
(3)使用FutureTask对象作为Thread对象的target来创建并启动新线程。
(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。

Demo
小例子如下:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //先使用Lambda表达式创建Callable<Integer>对象
        //使用FutureTask包装Callable对象
        FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)()->{
           int i =0;
           for( ;i < 10;i++){
               System.out.println(Thread.currentThread().getName() + "的循环变量i的值:" + i);
           }
           return i;
        });
        new Thread(task,"有返回值的线程").start();
        System.out.println(task.get());
    }
}
End
此方式优势是,只是实现Callable接口,还可以继承其他类。劣势是编程稍微复杂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值