JUC包工具类介绍二
JUC包工具类介绍二
异步任务
Callable
Callable接口定义一个异步任务,当Callable接口提交到ExecutorService进行异步执行时,返回结果通过Java Future获取。Callable接口同样可以获取任务执行时的异常。
public class MyCallable implements Callable<String> { @Override public String call() throws Exception { return String.valueOf(System.currentTimeMillis()); } } |
Callable 和 Runnable的区别:
两者都表示一个可以被其他线程执行的任务。Runnable的run方法没有返回值,任务发起线程也无法获取到任务执行中的已检查异常,只能获取到RuntimeException.而Callable可以获取返回值和异常。两者的设计上Runable是为了长时间的并发任务而设计,如网络连接,监听文件等。而Callable适合于返回一个结果的单次任务。
Java Future
Future表示一个异步计算的结果。当异步任务创建之后如Callable提交给ExecutorService之后,返回Future对象,Future接口提供获对异步任务的交互方法,如获取结果,取消任务等,检查任务状态。
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning) V get(); V get(long timeout, TimeUnit unit); boolean isCancelled(); boolean isDone(); } |
锁
锁用于避免资源竞争带来的异常。相比于Synchronized,可以提供线程资源唤醒顺序(公平锁),更细粒度的作用于(Synchronized只能作用于整个方法,Lock通过Lock和unLock方法控制),更丰富的控制(如等待超时等参数)
ReentrantLock
ReentrantLock是一个可重入锁的实现, 可重入锁表示持有锁的现成可以重新获取对锁进行锁定,相应的多次的锁定需要进行多次的unLock。
Lock lock = new ReentrantLock(); lock.lock(); //critical section lock.unlock(); |
公平锁: 公平锁是指等待锁的现成获取锁的顺序按照等待的顺序进行,而非公平锁表示不保证获取顺序。ReentrantLock创建时可以指定是否公平锁。公平锁必须使用带超时的tryLock方法。
ReadWriteLock
读写锁则是针对读写业务特性设计的锁。保证多线程可以同时读,但当存在写操作时,只能有一个线程持有,此时读操作也无法获取锁。
Read Lock: 如果当前没有写锁被占有,并且没有写锁的请求,则多线程可以获取读锁进行读操作。
Write Lock: 如果当前没有现成在进行读或写,只有一个线程可以锁定写锁。
JUC 下的读写锁实现:ReentrantReadWriteLock
ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); readWriteLock.readLock().lock(); readWriteLock.readLock().unlock(); readWriteLock.writeLock().lock(); readWriteLock.writeLock().unlock(); |
Atomic系列
Atomic系列对象提供了针对特定类型提供原子性操作的操作方法。主要是针对于单一操作因为Java字节码分析后实际是多个操作执行的原因,在并发环境下结果可能异常的情况。
AtomicBoolean\ AtomicInteger\ AtomicLong
提供了可以原子性对boolean变量进行读写操作,已经compareAndSet等高作操作的原子性。
AtomicBoolean atomicBoolean = new AtomicBoolean(true); boolean value = atomicBoolean.get(); atomicBoolean.set(false); boolean oldValue = atomicBoolean.getAndSet(false); boolean expectedValue = true; boolean newValue = false; boolean wasNewValueSet = atomicBoolean.compareAndSet( expectedValue, newValue); |
AtomicInteger和AtomicLong类型类似。
AtomicReference\AtomicStampedReference
AtomicReference 保证多线程对对象引用改变不会出现一个不一致的状态。
AtomicReference atomicReference = new AtomicReference();
atomicReference.set("New object referenced"); boolean exchanged = atomicStringReference.compareAndSet(initialReference, newReference); |
AtomicStampedReference则是为解决ABA问题而设计的。 ABA问题指的是当前对象是A,经过改变设置为B之后,又重新设置为A, 使用传统的compareAndSet方法进行设置时无法意识到A-B-A的改变过程而误认为对象一直为A没有改变过,从而进行了错误的操作。
AtomicStampedReference对引用的状态添加了时间戳的概念, 对象的完整状态必须包括对象本身以及设置时候的时间戳,因此即使是同一个值,不同的时间戳也就表示不同的状态。
String initialRef = "initial value referenced"; int initialStamp = 0; AtomicStampedReference<String> atomicStringReference = new AtomicStampedReference<String>( initialRef, initialStamp ); String newRef = "new value referenced"; int newStamp = initialStamp + 1; boolean exchanged = atomicStringReference .compareAndSet( initialRef, newRef, initialStamp, newStamp); System.out.println("exchanged: " + exchanged); //true exchanged = atomicStringReference .compareAndSet( initialRef, "new string", newStamp, newStamp + 1); System.out.println("exchanged: " + exchanged); //false exchanged = atomicStringReference .compareAndSet( newRef, "new string", initialStamp, newStamp + 1); System.out.println("exchanged: " + exchanged); //false exchanged = atomicStringReference .compareAndSet( newRef, "new string", newStamp, newStamp + 1); System.out.println("exchanged: " + exchanged); //true |
AtomicIntegerArray\AtomicLongArray\AtomicReferenceArray
AtomicIntegerArray 数组对象系列表示可以进行原子操作的数组。包括AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray。
int[] ints = new int[10]; ints[5] = 123; AtomicIntegerArray array = new AtomicIntegerArray(ints); int value = array.get(5); array.set(5, 999); boolean swapped = array.compareAndSet(5, 999, 123); int newValue = array.addAndGet(5, 3); |
CopyOnWriteArrayList\ CopyOnWriteArraySet
提供线程安全的ArrayList对象,实现上将对ArrayList的所有更新操作都作用在一个写副本上,并且通过ReentrantLock来保护并发更新。Set方法的源码如下:
public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); E oldValue = get(elements, index); if (oldValue != element) { int len = elements.length; //拷贝副本进行更新操作,并将新的副本设置为最新列表 Object[] newElements = Arrays.copyOf(elements, len); newElements[index] = element; setArray(newElements); } else { // Not quite a no-op; ensures volatile write semantics setArray(elements); } return oldValue; } finally { lock.unlock(); } } |
CopyOnWriteArraySet提供线程安全的Set操作,底层使用CopyOnWriteArrayList实现。
相关文章:
JUC包工具类介绍二
JUC包工具类介绍二 异步任务 Callable Callable接口定义一个异步任务,当Callable接口提交到ExecutorService进行异步执行时,返回结果通过Java Future获取。Callable接口同样可以获取任务执行时的异常。 public class MyCallable implements Callable&…...

第8章_聚合函数
文章目录 1 聚合函数介绍1.1 AVG和SUM函数1.2 MIN和Max函数1.3 COUNT函数演示代码 2 GROUP BY2.1 基本使用2.2 使用多个列分组2.3 演示代码 3 HAVING3.1 基本使用3.2 WHERE和HAVING的对比3.3 演示代码 4 SELECT的执行过程4.1 查询的结构4.2 SELECT执行顺序4.3 SQL的执行原理演示…...

Mysql8与mariadb的安装与常用设置
一、v10服务器mariadb的安装与常用设置 V10服务器默认安装了mariadb数据库。也可使用命令sudo yum install mariadb手动安装或升级默认安装的版本。 1.1 修改数据库密码 systemctl restart mariadb,重启mariadb服务;mysql -u root -p,要求输入密码直接回车&#…...
深入剖析Golang中单例模式
前言 虽说Golang并不是C、Java这种传统的面向对象语言,而是偏向于面向接口编程的语言。但是Golang依旧有接口、结构体、组合等概念去模拟所谓面向对象中非常重要的设计模式。基于面向对象的模型去编写代码往往能编写成高内聚、低耦合、扩展性极强、难出bug的高质量…...

Java之SpringCloud Alibaba【八】【Spring Cloud微服务Gateway整合sentinel限流】
一、Gateway整合sentinel限流 网关作为内部系统外的一层屏障,对内起到-定的保护作用,限流便是其中之- - .网关层的限流可以简单地针对不同路由进行限流,也可针对业务的接口进行限流,或者根据接口的特征分组限流。 1、添加依赖 <dependency><groupId>c…...

深入解析 Redis 分布式锁原理
一、实现原理 1.1 基本原理 JDK 原生的锁可以让不同线程之间以互斥的方式来访问共享资源,但如果想要在不同进程之间以互斥的方式来访问共享资源,JDK 原生的锁就无能为力了。此时可以使用 Redis 来实现分布式锁。 Redis 实现分布式锁的核心命令如下&am…...

[unity]多脚本情况下update函数的执行顺序
序 有的时候,执行某些脚本时会有先后顺序的要求。unity是按什么顺序来执行脚本的?如何设置? 默认的执行顺序 官方文档里面有个很长的图: Unity - Manual: Order of execution for event functions (unity3d.com) 根据文档&…...
Maven中<scope>中等级的区别
标签指定了依赖项的级别吗,默认是compile (编译)。意味着依赖项将会在编译时和运行时都被包含在项目中 <scope> 标签指定了依赖项的级别为 import 。除了 import 级别,Maven还支持以下几种级别: compile &#x…...

小明和完美序列(HashMap、Map、Entry)
小明和完美序列 知识点: //导包:HashMap、Map、Entry import java.util.HashMap; import java.util.Map; import java.util.Map.Entry;public class Main {public static void main(String [] args) { //创建Map(HashMap)对象 M…...

【hexo博客配置】hexo icarus主题配置
配置icarus 步骤一:下载icarus github网址:[hexo-theme-icarus](ppoffice/hexo-theme-icarus: A simple, delicate, and modern theme for the static site generator Hexo. (github.com)) 可以从这个网址上下载zip文件,解压后,…...

建表时如何合理选择字段类型
前言 我们在建表的时候关于字段类型的选择会有这么几类人: 严谨型 严格调研每个字段可能的大小,然后根据不同字段类型的限制,进行选择,这一类人在创建关系型数据表的时候是没有问题的。图自己省事型 把所有字段都设置为String&a…...

Qt Creator插件
这里以Qt Creator 4.15.2版本的源码为示例进行分析 源码结构如下,为了追溯其插件加载过程,从main.cpp入手 Qt Creator的插件目录,生成的插件,好几十个呢 Qt Creator插件的读取 int main(int argc, char **argv)中以下代码创建插…...

AI全栈大模型工程师(十九)Semantic Kernel
文章目录 Semantic KernelSK 的开发进展SK 的生态位SK 基础架构后记 Semantic Kernel 先比较下 Semantic Kernel 和 LangChain。 Semantic KernelLangChain出品公司微软LangChain AI支持语言Python、C#、Java、TypeScriptPython、TypeScript开源协议MITMIT被应用在Microsoft …...
Dubbo 的服务请求失败怎么处理?
本文引用mic老师面试文档 今天分享的面试题,几乎是 90%以上的互联网公司都会问到的问题。 “Dubbo 的服务请求失败怎么处理”? 对于这个问题,我们来看一下普通人和高手的回答。 普通人 嗯… 我记得, Dubbo 请求处理失败以后&a…...

存储虚拟化讲解
目录 存储虚拟化的分类 按照虚拟化发生的位置分类 基于主机的虚拟化 基于存储设备的虚拟化 基于网络的虚拟化 按照虚拟化实现方式分类 带内虚拟化 带外虚拟化 按照虚拟化的对象分类 虚拟机磁盘类型 按照磁盘的特性分类 按照磁盘的安全性分类 什么是虚拟化 存储虚拟…...

[云原生案例2.1 ] Kubernetes的部署安装 【单master集群架构 ---- (二进制安装部署)】节点部分
文章目录 1. 常见的K8S安装部署方式1.1 Minikube1.2 Kubeadm1.3 二进制安装部署 2. Kubernetes单master集群架构 ---- (二进制安装部署)2.1 前置准备2.2 操作系统初始化2.3 部署 docker引擎 ---- (所有 node 节点)2.4 部署 etcd 集…...
Apache ActiveMQ 远程代码执行漏洞影响范围
漏洞相关信息 项目内容漏洞名称Apache ActiveMQ 远程代码执行漏洞 漏洞描述 组件名称:Apache ActiveMQ 漏洞类型:远程代码执行 利用条件: 1、用户认证:不需要用户认证 2、触发方式:网络可访问 ActiveMQ的61616端…...

如何规划并新建大数据平台的独立生产域?5步走
一般来说,大数据平台包括以下4类数据生产域——生产生态环境(正式生产环境)、开发和测试环境、培训和演示环境、灾备环境。各生产域在由平台提供资源、安全、监控、故障恢复等保障的同时,不同的生产域之间还需要严格隔离ÿ…...

工程车云管家|叉车智能管家安卓主板方案
工程车云管家是一款功能强大的设备管理和调度系统,它可以实时追踪工程车或机械设备的地理位置、视频、行驶轨迹、油位油耗、工作时长和地点、以及运行状况等信息,并将这些数据通过云平台存储、分析,并发送到管理者的手机上。这使得管理者能够…...

大数据学习之Spark性能优化
文章目录 Spark三种任务提交模式宽依赖和窄依赖StageSpark Job的三种提交模式 Shuffle机制分析未优化的Hash Based Shuffle优化后的Hash Based ShuffleSort-Based Shuffle Spark之checkpointcheckpoint概述checkpoint与持久化的区别checkPoint的使用checkpoint源码分析 Spark程…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...

云原生安全实战:API网关Envoy的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口,负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...

Linux入门课的思维导图
耗时两周,终于把慕课网上的Linux的基础入门课实操、总结完了! 第一次以Blog的形式做学习记录,过程很有意思,但也很耗时。 课程时长5h,涉及到很多专有名词,要去逐个查找,以前接触过的概念因为时…...