多线程与高并发(八):Callable

在Java中,创建线程除了继承Thread类和实现Runnable接口之外,还可以通过实现Callable接口创建线程。

一、如何通过实现Callable接口创建线程

public class MyThread implements Callable<Object> {
    @Override
    public Object call() throws Exception {
        return "this is my thread";
    }
}

 

二、Callable与Runnable的区别

1、Callable可以有返回值。

2、Callable可以抛出异常。

 

三、如何使用Callable

1、Future接口

由于实现Callable接口可以有返回值,但返回值是通过异步计算而得到的,那么该如何得到call方法的返回值呢?为此,可以使用Future接口,顾名思义,它可以保存call方法在未来计算出的返回值。

首先了解Future的几个方法:

cancel(boolean):用来停止一个任务,如果任务可以停止(通过入参来进行判断),则返回true,如果任务已经完成或者已经停止,或者这个任务无法停止,则会返回false。

get:用于获取call方法返回的结果,如果任务完成,它将立即返回结果,否则等待

isDone:如果任务完成返回true,否则返回false。

 

2、FutureTask

FutureTask实现了RunnableFuture接口,相当于实现了Future接口和Runnable接口。即FutureTask既可以执行也可以保存结果。

如何使用FutureTask:

① 通过Thread.start执行call方法:

由于FutureTask实现了Runnable接口,故可以使用Thread.start(Runnable task)开启线程执行call方法。

public class CallableDemo implements Callable<String> {
    @Override
    public String call() throws Exception {
        TimeUnit.SECONDS.sleep(1);
        return "callable";
    }

    public static void main(String[] args) {
        // 构造FutureTask FutureTask(Callable<V> callable)
        FutureTask<String> futureTask = new FutureTask<>(new CallableDemo());
        // 执行futureTask
        new Thread(futureTask).start();
        try {
            // 通过get方法获取到异步线程的值
            System.out.println(futureTask.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

② 通过线程池执行call方法:

由于FutureTask实现了Runnable接口,故可以使用ExecutorService.submit(Runnable task)用线程池执行call方法。

public static void main(String[] args) {
	// 构造FutureTask FutureTask(Callable<V> callable)
	FutureTask<String> futureTask = new FutureTask<>(new CallableDemo());
	// 执行futureTask
	ExecutorService threadPool = Executors.newSingleThreadExecutor();
	threadPool.submit(futureTask);
	try {
		// 通过get方法获取到异步线程的值
		System.out.println(futureTask.get());
	} catch (InterruptedException | ExecutionException e) {
		e.printStackTrace();
	}
	// 关闭线程池
	threadPool.shutdown();
}

 

3、线程池:

可以通过线程池执行Callable的call方法得到返回值。

public static void main(String[] args) {
	// 执行futureTask
	ExecutorService threadPool = Executors.newSingleThreadExecutor();
	Future<String> future = threadPool.submit(new CallableDemo());
	try {
		// 通过get方法获取到异步线程的值
		System.out.println(future.get());
	} catch (InterruptedException | ExecutionException e) {
		e.printStackTrace();
	}
	// 关闭线程池
	threadPool.shutdown();
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值