当前位置: 首页 > news >正文

javaJUC基础

JUC基础知识

多线程

管程

Monitor,也就是平时所说的锁。Monitor其实是一种同步机制,它的义务是保证(同一时间)只有一个线程可以访问被保护的数据和代码块,JVM中同步是基于进入和退出监视器(Monitor管程对象)来实现,每个对象实例都会有一个Monitor对象,底层是由C++语言来实现。

  • 补:Monitor对象并不会随着Java对象的销毁而销毁。

    Java对象是在Java中创建的,而Monitor是与Java对象关联的、由JVM内部管理的机制。Monitor的创建和销毁并不直接对应于Java对象的创建和销毁。更确切地说,当Java对象被用作同步锁时,JVM会为该对象关联一个Monitor;而当该对象不再被用作同步锁,或者对象被垃圾回收时,与其关联的Monitor可能会被JVM内部释放或重新利用。

?:为什么是同步机制,不是互斥机制

- 同步机制与互斥机制并不矛盾,同步机制包含了互斥以及协作

线程分类

用户线程

工作线程,完成业务操作

守护线程

一种特殊的为其它线程服务的线程,在后台默默完成一些系统性的任务(典型:垃圾回收线程)。做为一个服务线程,当服务对象没有了,就会伴随JVM一同结束工作。

?:怎么设置成守护线程?

Thread t = new Thread(() -> {});
t.setDaemon();
t.start();
/**
必须在start()开始前设置,不然会抛异常
*/

CompletableFuture

Future接口

Future是Java5新加的一个接口,它提供一种异步并行计算的功能,如果主线程需要执行一个很耗时的计算任务,我们会就可以通过Future把这个任务放进异步线程中执行,主线程继续处理其他任务或者先行结束,再通过Future获取计算结果

  • 功能

定义操作异步任务执行的一些方法,如获取异步任务的执行结果、取消异步任务的执行、判断任务是否被取消、判断任务执行是否完毕等。

  • 实现类 :FutureTask

在这里插入图片描述

FutureTask<String> futureTask = new FutureTask<>(() -> "Hello");
new Thread(futureTask).start();
try {System.out.println(futureTask.get());
} catch (InterruptedException | ExecutionException e) {e.printStackTrace();
}
  • 优点

Future+线程池异步多线程任务配合,能显著提高程序的运行效率。

  • 缺点
  • get()阻塞

一旦调用get()方法求结果,一旦调用不见不散,非要等到结果才会离开,不管你是否计算完成,如果没有计算完成容易程序堵塞。

  • isDone()轮询

轮询的方式会耗费无谓的cpu资源,而且也不见得能及时得到计算结果,如果想要异步获取结果,通常会以轮询的方式去获取结果,尽量不要阻塞。

FutureTask<String> futureTask = new FutureTask<>(() -> {TimeUnit.SECONDS.sleep(5);return "hello world";
});new Thread(futureTask).start();while (true) {if (futureTask.isDone()) {try {System.out.println(futureTask.get());return;} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}} else {try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("程序正在运行");}
}

CompletableFuture 对 Future的改进

Future 在实际杂的任务中遇到了众多问题:

  • 轮询耗时,不能回调
  • 怎么更好与线程池组合使用
  • 多个任务同步问题

jdk8中出现了CompletableFuture

  • 类架构

在这里插入图片描述

  • 创建
    在这里插入图片描述
  • 回调
ExecutorService executorService = Executors.newFixedThreadPool(3);
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "---come in");int result = ThreadLocalRandom.current().nextInt(10);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}if (result > 5) { //模拟产生异常情况int i = 10 / 0;}System.out.println("----------1秒钟后出结果" + result);return result;
}, executorService).whenComplete((v, e) -> {if (e == null) {System.out.println("计算完成 更新系统" + v);}
}).exceptionally(e -> {e.printStackTrace();System.out.println("异常情况:" + e.getCause() + " " + e.getMessage());return null;
});
System.out.println(Thread.currentThread().getName() + "先去完成其他任务");
executorService.shutdown();

chain链式调用

@Accessors(chain = true)//开启链式调用

常用函数

  • get()

  • get(long timeout,TimeUnit unit)

  • join – 不抛异常

  • getNow() 完成返回正常值,否则备胎值

  • complate(T val) 是否打断get()直接返回val

  • thenApply() 计算存在依赖关系,串行化,且当前异常不进行下一步

  • handle() 存在依赖,串行化,异常也进行下一步

  • thenAccpt() 接受任务结果,不返回

  • thenRun() A执行完执行B,不需要A的结果

  • applyToEither() 谁快用谁

  • thenCombine 合并计算结果

线程池

如果没有传入自定义线程池,都用默认线程池ForkJoinPool

传入一个线程池,如果你执行第一个任务时,传入了一个自定义线程池

调用thenRun方法执行第二个任务时,则第二个任务和第一个任务时共用同一个线程池

调用thenRunAsync执行第二个任务时,则第一个任务使用的是你自定义的线程池,第二个任务使用的是ForkJoin线程池

备注:可能是线程处理太快,系统优化切换原则, 直接使用main线程处理,thenAccept和thenAcceptAsync,thenApply和thenApplyAsync等,之间的区别同理。

如何在Springboot如何在注册线程池呢?点击查看

http://www.lryc.cn/news/447279.html

相关文章:

  • std::distance 函数介绍
  • 如何在Windows和Linux之间实现粘贴复制
  • 【第十七章:Sentosa_DSML社区版-机器学习之异常检测】
  • 【Vue】为什么 Vue 不使用 React 的分片更新?
  • 大学生科技竞赛系统小程序的设计
  • 什么是聚集索引?
  • Centos/fedora/openEuler 终端中文显示配置
  • 使用kaggle命令下载数据集和模型
  • 生信初学者教程(十一):数据校正
  • JS设计模式之桥接模式:搭建跨越维度的通路
  • 苹果电脑系统重磅更新——macOS Sequoia 15 系统 新功能一 览
  • DoppelGanger++:面向数据库重放的快速依赖关系图生成
  • Linux(含麒麟操作系统)如何实现多显示器屏幕采集录制
  • calibre-web默认左上角字体修改
  • 考研数据结构——C语言实现归并排序
  • LDO功率管选取NMOS和PMOS区别
  • 【Linux】进程的标识符、状态(超详解)
  • Elasticsearch 启动后在浏览器输入http://localhost:9200 访问失败
  • javascript中new操作符的工作原理
  • 基于springboot+vue 旅游网站的设计与实现
  • Ansible集群服务部署案例
  • 探索AI编程新境界:aider库揭秘
  • SQL Server 2012 ldf日志文接太大的截断和收缩日志处理
  • java日志门面之JCL和SLF4J
  • Oracle DB运维常用的视图及数据字典
  • vue.config.js devServer中changeOrigin的作用
  • 基于Ubuntu 20.04 LTS上部署MicroK8s(最小生产的 Kubernetes)
  • Spring:项目中的统一异常处理和自定义异常
  • 有点快要跟不上时代的感觉
  • 【pytorch】pytorch入门4:神经网络的卷积层