java高并发系列 - 第31天:获取线程执行结果,这6种方法你都知道?

总结:心得体会

既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。

学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。

面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

这是java高并发系列第31篇。

环境:jdk1.8。

java高并发系列已经学了不少东西了,本篇文章,我们用前面学的知识来实现一个需求:

在一个线程中需要获取其他线程的执行结果,能想到几种方式?各有什么优缺点?

结合这个需求,我们使用6种方式,来对之前学过的知识点做一个回顾,加深记忆。

方式1:Thread的join()方法实现


代码:

package com.itsoku.chat31;

import java.sql.Time;

import java.util.concurrent.*;

/**

* 跟着阿里p7学并发,微信公众号:javacode2018

*/

public class Demo1 {

//用于封装结果

static class Result<T> {

T result;

public T getResult() {

return result;

}

public void setResult(T result) {

this.result = result;

}

}

public static void main(String[] args) throws ExecutionException, InterruptedException {

System.out.println(System.currentTimeMillis());

//用于存放子线程执行的结果

Result<Integer> result = new Result<>();

//创建一个子线程

Thread thread = new Thread(() -> {

try {

TimeUnit.SECONDS.sleep(3);

result.setResult(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

});

thread.start();

//让主线程等待thread线程执行完毕之后再继续,join方法会让当前线程阻塞

thread.join();

//获取thread线程的执行结果

Integer rs = result.getResult();

System.out.println(System.currentTimeMillis());

System.out.println(System.currentTimeMillis() + “:” + rs);

}

}

输出:

1566733162636

1566733165692

1566733165692:10

代码中通过join方式阻塞了当前主线程,当thread线程执行完毕之后,join方法才会继续执行。

join的方式,只能阻塞一个线程,如果其他线程中也需要获取thread线程的执行结果,join方法无能为力了。

关于join()方法和线程更详细的使用,可以参考:线程的基本操作

方式2:CountDownLatch实现


代码:

package com.itsoku.chat31;

import java.util.concurrent.*;

/**

* 跟着阿里p7学并发,微信公众号:javacode2018

*/

public class Demo2 {

//用于封装结果

static class Result<T> {

T result;

public T getResult() {

return result;

}

public void setResult(T result) {

this.result = result;

}

}

public static void main(String[] args) throws ExecutionException, InterruptedException {

System.out.println(System.currentTimeMillis());

CountDownLatch countDownLatch = new CountDownLatch(1);

//用于存放子线程执行的结果

Demo1.Result<Integer> result = new Demo1.Result<>();

//创建一个子线程

Thread thread = new Thread(() -> {

try {

TimeUnit.SECONDS.sleep(3);

result.setResult(10);

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

countDownLatch.countDown();

}

});

thread.start();

//countDownLatch.await()会让当前线程阻塞,当countDownLatch中的计数器变为0的时候,await方法会返回

countDownLatch.await();

//获取thread线程的执行结果

Integer rs = result.getResult();

System.out.println(System.currentTimeMillis());

System.out.println(System.currentTimeMillis() + “:” + rs);

}

}

输出:

1566733720406

1566733723453

1566733723453:10

上面代码也达到了预期效果,使用CountDownLatch可以让一个或者多个线程等待一批线程完成之后,自己再继续;CountDownLatch更详细的介绍见:JUC中等待多线程完成的工具类CountDownLatch,必备技能

方式3:ExecutorService.submit方法实现


代码:

package com.itsoku.chat31;

import java.util.concurrent.*;

/**

* 跟着阿里p7学并发,微信公众号:javacode2018

*/

public class Demo3 {

public static void main(String[] args) throws ExecutionException, InterruptedException {

//创建一个线程池

ExecutorService executorService = Executors.newCachedThreadPool();

System.out.println(System.currentTimeMillis());

Future<Integer> future = executorService.submit(() -> {

try {

TimeUnit.SECONDS.sleep(3);

} catch (InterruptedException e) {

e.printStackTrace();

}

return 10;

});

//关闭线程池

executorService.shutdown();

System.out.println(System.currentTimeMillis());

Integer result = future.get();

System.out.println(System.currentTimeMillis() + “:” + result);

}

}

输出:

1566734119938

1566734119989

1566734122989:10

使用ExecutorService.submit方法实现的,此方法返回一个Futurefuture.get()会让当前线程阻塞,直到Future关联的任务执行完毕。

相关知识:

  1. JAVA线程池,这一篇就够了

  2. JUC中的Executor框架详解1

  3. JUC中的Executor框架详解2

方式4:FutureTask方式1


代码:

package com.itsoku.chat31;

import java.util.concurrent.*;

/**

* 跟着阿里p7学并发,微信公众号:javacode2018

*/

public class Demo4 {

public static void main(String[] args) throws ExecutionException, InterruptedException {

System.out.println(System.currentTimeMillis());

//创建一个FutureTask

FutureTask<Integer> futureTask = new FutureTask<>(() -> {

try {

TimeUnit.SECONDS.sleep(3);

} catch (InterruptedException e) {

e.printStackTrace();

}

return 10;

});

//将futureTask传递一个线程运行

new Thread(futureTask).start();

System.out.println(System.currentTimeMillis());

//futureTask.get()会阻塞当前线程,直到futureTask执行完毕

Integer result = futureTask.get();

System.out.println(System.currentTimeMillis() + “:” + result);

}

}

输出:

1566736350314

1566736350358

1566736353360:10

代码中使用FutureTask实现的,FutureTask实现了Runnable接口,并且内部带返回值,所以可以传递给Thread直接运行,futureTask.get()会阻塞当前线程,直到FutureTask构造方法传递的任务执行完毕,get方法才会返回。关于FutureTask详细使用,请参考:JUC中的Executor框架详解1

方式5:FutureTask方式2

Java高频面试专题合集解析:

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

更多Java架构进阶资料展示

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

9)]

当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!

[外链图片转存中…(img-KLTHXgQO-1715455497140)]

更多Java架构进阶资料展示

[外链图片转存中…(img-K7DzbCk8-1715455497140)]

[外链图片转存中…(img-IlDPNl0f-1715455497141)]

[外链图片转存中…(img-19dovT2f-1715455497142)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值