欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-10 19:30:56
在Java中,创建线程除了继承Thread类和实现Runnable接口之外,还可以通过实现Callable接口创建线程。一、如何通过实现Callable接口创建线程public class MyThread implements Callable { @Override public Object call() throws Exception { return "this is my thread"; }}二、Cal....

在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

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

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();
}

 

 

本文地址:https://blog.csdn.net/sinat_32144323/article/details/114274289

相关标签: 多线程与高并发