Java高并发编程中Future的使用及详细介绍 您所在的位置:网站首页 mechanic造句子 Java高并发编程中Future的使用及详细介绍

Java高并发编程中Future的使用及详细介绍

2024-01-12 08:59| 来源: 网络整理| 查看: 265

Java高并发编程中Future的使用及详细介绍-刘宇 一、什么是Future?二、Future的结构图三、Future中的方法1、cancel方法2、isCancelled方法3、isDone方法4、get方法5、超时get方法 四、Future练习1、get方法练习2、打断get方法3、其他方法练习

作者:刘宇 CSDN博客地址:https://blog.csdn.net/liuyu973971883 有部分资料参考,如有侵权,请联系删除。如有不正确的地方,烦请指正,谢谢。

一、什么是Future?

在我们并发编程中,使用thread或runnable接口都不能获取异步的执行结果,因为他们都没有返回值。而通过实现Callable接口和Future就可以获取异步执行的结果,当异步执行结束后,返回结果将保存在我们的Future中。使用Future就可以让我们暂时去处理其他的任务,等异步任务执行完毕再返回其结果。

二、Future的结构图

在这里插入图片描述

三、Future中的方法 1、cancel方法

取消任务,如果任务成功被取消,则返回true;如果任务已成功结束或者已被取消,则返回false。

取消正在被执行的任务,其实内部还是通过interrupt。如果任务中没有可被interrupt的方法怎么办,我们可以使用ThreadFactory,关于ThreadFactory的使用可看我前面的博客:点击查看详情任务取消后无法通过Future获取值;mayInterruptIfRunning:是否取消正在运行的任务 boolean cancel(boolean mayInterruptIfRunning); 2、isCancelled方法

返回该任务是否被取消

boolean isCancelled(); 3、isDone方法

返回该任务是否结束,包含:正常结束、异常、取消

boolean isDone(); 4、get方法

获取任务结束后返回的结果,如果调用时,任务还没有结束,则会进行阻塞线程,直到任务完成。该阻塞是可以被打断的,打断的线程是调用get方法的线程,被打断后原任务会依旧继续执行。

V get() throws InterruptedException, ExecutionException; 5、超时get方法

获取任务结束后返回的结果,如果调用时,任务还没有结束,则会进行阻塞线程,等待一定时间,如果在规定时间内任务结束则返回结果,否则抛出TimeoutException,超时后任务依旧会继续执行。该阻塞是可以被打断的,打断的线程是调用get方法的线程,被打断后原任务会依旧继续执行。

V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; 四、Future练习 1、get方法练习 package com.brycen.part3.threadpool; import java.util.concurrent.*; public class FutureExample { public static void main(String[] args) { testGet();//不超时get练习 // testGetWithTimeOut();//超时get练习 } private static void testGet(){ ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); //提交一个callable Future result = threadPoolExecutor.submit(() -> { System.out.println("=======callable start========"); TimeUnit.SECONDS.sleep(10); System.out.println("=======callable end=========="); return 10; }); try { //模拟做其他事情 TimeUnit.SECONDS.sleep(1); System.out.println("=======do other thing========"); //阻塞等待结果 System.out.println(result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("==========main end==========="); } private static void testGetWithTimeOut() { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); //提交一个callable Future result = threadPoolExecutor.submit(() -> { System.out.println("=======callable start========"); TimeUnit.SECONDS.sleep(10); System.out.println("=======callable end=========="); return 10; }); try { //模拟做其他事情 TimeUnit.SECONDS.sleep(1); System.out.println("=======do other thing========"); //阻塞等待3秒,任务还没有结束则抛出超时异常,但是任务会继续执行 System.out.println(result.get(3,TimeUnit.SECONDS)); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); } System.out.println("==========main end==========="); } }

运行结果:

testGet运行结果: =======callable start======== =======do other thing======== =======callable end========== 10 ==========main end=========== testGetWithTimeOut运行结果:

可以看出即使是超时了,异步任务依然会继续执行。

=======callable start======== =======do other thing======== java.util.concurrent.TimeoutException at java.util.concurrent.FutureTask.get(FutureTask.java:205) at com.brycen.part3.threadpool.FutureExample.testGetWithTimeOut(FutureExample.java:48) at com.brycen.part3.threadpool.FutureExample.main(FutureExample.java:8) ==========main end=========== =======callable end========== 2、打断get方法 package com.brycen.part3.threadpool; import java.util.concurrent.*; public class FutureExample { public static void main(String[] args) { testGetWithInterrupt(); } private static void testGetWithInterrupt() { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); //提交一个callable Future result = threadPoolExecutor.submit(() -> { System.out.println("=======callable start========"); TimeUnit.SECONDS.sleep(10); System.out.println("=======callable end=========="); return 10; }); try { //模拟做其他事情 TimeUnit.SECONDS.sleep(1); System.out.println("=======do other thing========"); //获取到执行get方法的线程 Thread callerThread = Thread.currentThread(); //开启一共线程异步打断执行get方法的线程 new Thread(new Runnable() { @Override public void run() { try { //等待1秒,确保get方法被执行 TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } callerThread.interrupt(); } }).start(); //阻塞等待结果 System.out.println(result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("==========main end==========="); } }

运行结果:

可以看出即使get方法被打断了,异步任务依然会继续执行。

=======callable start======== =======do other thing======== java.lang.InterruptedException at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:404) at java.util.concurrent.FutureTask.get(FutureTask.java:191) at com.brycen.part3.threadpool.FutureExample.testGetWithInterrupt(FutureExample.java:89) at com.brycen.part3.threadpool.FutureExample.main(FutureExample.java:9) ==========main end=========== =======callable end========== 3、其他方法练习 package com.brycen.part3.threadpool; import java.util.concurrent.*; public class FutureExample2 { public static void main(String[] args) throws InterruptedException, ExecutionException { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); //提交一个callable Future result = threadPoolExecutor.submit(() -> { System.out.println("=======callable start========"); try { TimeUnit.SECONDS.sleep(10); }catch (Exception e){ e.printStackTrace(); } System.out.println("=======callable end=========="); return 10; }); //休眠100毫秒,确保任务被执行 TimeUnit.MILLISECONDS.sleep(100); //判断任务是否结束 System.out.println(result.isDone()); //取消正在执行的任务,内部还是使用的线程中断,如果任务中没有可被interrupted的方法怎么办,我们可以使用ThreadFactory System.out.println(result.cancel(true)); //第二次取消返回false,因为任务已被取消过 System.out.println(result.cancel(true)); //任务出现异常、被取消、完成都会返回true System.out.println(result.isDone()); //被取消后虽然任务会继续执行,但是无法再获取到返回值,抛出CancellationException System.out.println("result: "+result.get()); } }

运行结果:

=======callable start======== false true false true =======callable end========== Exception in thread "main" java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at com.brycen.part3.threadpool.FutureExample2.lambda$main$0(FutureExample2.java:12) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) java.util.concurrent.CancellationException at java.util.concurrent.FutureTask.report(FutureTask.java:121) at java.util.concurrent.FutureTask.get(FutureTask.java:192) at com.brycen.part3.threadpool.FutureExample2.main(FutureExample2.java:28)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有