首页 > 编程语言 >Java多线程 Callable和Future

Java多线程 Callable和Future

时间:2022-11-11 10:33:35浏览次数:49  
标签:执行 Runnable Java Callable Future 线程 多线程 public


目录

  • ​​一、说明​​
  • ​​二、理解​​
  • ​​三、实现​​
  • ​​1.实现接口​​
  • ​​2.执行线程​​

一、说明

Java 提供了三种创建线程的方法

  • 实现 ​​Runnable​​接口
  • 继承 ​​Thread​​类本身
  • 通过 ​​Callable​​​和 ​​Future​​ 创建线程

Callable和Future的引入

  • 继承​​Thread​​​或实现​​Runnable​​接口,任务执行完成后无法获取执行结果
  • 而要获取执行结果,必须通过共享变量或者使用线程通信的方式来达到效果
  • Java 1.5 开始引入了​​Callable​​​和​​Future​​,执行任务完成后可获取执行结果,简单来说就是一个产生结果,一个拿到结果

ExecutorService

  • ​ExecutorService​​​是Java中对线程池定义的一个接口,继承​​Executor​​​接口,用于管理线程对象,可以使用 ​​Executors​​​工厂类来创建​​ExecutorService​​的实例(即线程池)
ExecutorService executorService1 = Executors.newSingleThreadExecutor();  
ExecutorService executorService2 = Executors.newFixedThreadPool(10);
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
  • ​ExcutorService​​提供的三种方法都有相应的结果返回
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
  • 同时​​Executors​​​类提供方法能把​​Runnable​​​对象包装成​​Callable​​对象
public static Callable<Object> callable(Runnable task) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<Object>(task, null);
}
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}

二、理解

Callable

  • ​java.lang​​​包下​​Runnable​​​接口​​.run()​​​方法返回类型为​​void​
public interface Runnable {
public abstract void run();
}
  • ​java.util.concurrent​​​包下​​Callable​​​接口,​​.call()​​​方法返回的类型为传递进来的​​V - Value​​(值)类型
public interface Callable<V> {
V call() throws Exception;
}

实现方法

  • ​Runnable​​​或​​Callable​​​实现类使用​​ExecutorSevice​​​接口的​​.submit()​​​方法提交,不使用没有返回值的​​.execute()​​方法

Future

  • ​java.util.concurrent​​​包下​​Future<V>​​​接口,对​​Runnable​​​或​​Callable​​对象执行任务完成后获取执行结果
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;
}
  • ​mayInterruptRunning​​ 表示是否中断执行中的线程
  • ​boolean cancel()​​ 尝试取消任务的执行,如果任务已经完成或已被取消,则返回false;如果任务已经启动,将以中断执行线程的方式停止该任务,停止成功则返回true
  • ​boolean isDone()​​若任务完成,则返回true
  • ​boolean isCancelled()​​ 若任务在完成前取消,则返回true
  • ​get()​​ 获取执行结果,必须等待任务完成后才返回结果
  • ​get(long timeout, TimeUnit unit)​​ 获取执行结果,timeout表示等待的最长时间,unit表示时间单位,在指定时间内还没获取到结果,则返回null

三、实现

1.实现接口

创建​​CallableThreadDemo​​​类实现​​Callable​​接口

public class CallableThreadDemo implements Callable{
@Override
public String call() throws Exception {
System.out.println("Callable子线程: " +Thread.currentThread().getName()+ " 开启");
return "我是Callable子线程: " +Thread.currentThread().getName()+ " 产生的结果";
}
}

2.执行线程

创建​​CallableTest​​​类执行测试,将创建好的线程对象通过​​.submit()​​​方法提交到线程池去执行,线程执行后,返回值​​Future​​可被拿到

public class CallableTest {
public static void main(String[] args) {
// 1.创建线程池
ExecutorService executorService = Executors.newSingleThreadExecutor();
// 2.创建Callable子线程对象任务
CallableThreadDemo callableThread_1 = new CallableThreadDemo();
// 3.提交任务到线程池
Future future = executorService.submit(callableThread_1);
// 4.获取执行结果
try {
System.out.println("主线程开始执行");

System.out.println("主线程要取得Callable子线程的结果");
if (future.get()!=null){
//输出获取的结果
System.out.println(future.get());
}else {
//输出未获取到结果
System.out.println("future.get()未获取到结果");
}
} catch (InterruptedException e){
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
// 5.关闭线程池
executorService.shutdown();
System.out.println("主线程执行完成");
}
}

Java多线程 Callable和Future_java


标签:执行,Runnable,Java,Callable,Future,线程,多线程,public
From: https://blog.51cto.com/u_15872973/5843054

相关文章

  • Java多线程 Future和FutureTask的区别
    目录​​一、说明​​​​二、理解​​​​三、实现​​​​1.实现接口​​​​2.使用Future​​​​3.使用FutureTask​​一、说明Future和FutureTask的关系Future是一个......
  • Java多线程 ThreadPoolExecutor-RejectedExecutionHandler拒绝执行策略
    目录​​一、说明​​​​二、理解​​​​三、实现​​​​1.AbortPolicy​​​​2.DiscardPolicy​​​​3.DiscardOldestPolicy​​​​4.CallerRunsPolicy​​​​5.自......
  • Java多线程 线程池Executor框架
    目录​​一、说明​​​​二、理解​​​​Executor​​​​ExecutorService​​​​Executors​​​​三、实现​​​​1.newSingleThreadExecutor​​​​2.newFixedThr......
  • 8:Spring MVC-Java Spring
    目录​​8.1WEB开发模式一​​​​8.2WEB开发模式二​​​​8.3SpringMVC介绍​​​​8.4SpringMVC主要组件​​​​8.5SpringMVC处理流程​​​​8.6SpringMVC的......
  • Java Web项目中使用RSA加密数据
    在Web项目中有些时候需要对传输的数据加密后再传输到服务端进行解密使用,这里采用RSA进行公钥加密私钥解密的模式会有较高的安全性。这里选用的工具库是 JSEncrypt.js ......
  • 硬核剖析Java锁底层AQS源码,深入理解底层架构设计
    我们常见的并发锁ReentrantLock、CountDownLatch、Semaphore、CyclicBarrier都是基于AQS实现的,所以说不懂AQS实现原理的,就不能说了解Java锁。上篇文章讲了AQS的加锁流程,这......
  • Java并发编程——基础知识(一)
    1.进程与线程1.1基本概念进程:对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发线程:进程的子任务,是CPU调度和分派的基本单位,用于保证程序......
  • Java组合异步编程(2)
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ 多数码农在开发的时候,要么处理同步应用,要么处理异步。但是如果能学会使用CompletableFuture,就会具备一种神奇的能力:将同......
  • 定位java程序中占用cpu最高的线程堆栈信息
    找出占用cpu最高的线程堆栈信息在java编码中,有时会因为粗心导致cpu占用较高的情况,为了避免影响程序的正常运行,需要找到问题并解决。这里模拟一个cpu占用较高的场景,并尝试......
  • Java MAC环境Intellij2022配置Servlet和Tomcat
    1、下载安装Tomcat官网:https://tomcat.apache.org/download-90.cgi ->download 下载完放入自定义路径,需要记住!这样算下载好了,详细-> https://blog.csdn.net/qq_44......