CAS

ConcurrentHashMap 核心源码解析

余生颓废 提交于 2020-04-20 03:02:44
人只应当忘却自己而爱别人,这样人才能安静、幸福高尚。 ——托尔斯泰《安娜•卡列尼娜》 0 前言 线程安全的 Map - ConcurrentHashMap,让我们一起研究和 HashMap 相比有何差异,为何能保证线程安全呢. 1 继承体系 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gkf7KyhC-1587048420294)(https://user-gold-cdn.xitu.io/2020/4/13/1716f691bd3ef39d “图片标题”)] 与 HashMap 很相似,数组、链表结构几乎相同,都实现了 Map 接口,继承了 AbstractMap 抽象类,大多数的方法也都是相同的,ConcurrentHashMap 几乎包含 HashMap所有方法. 2 属性 bin数组.第一次插入时才延迟初始化.大小始终是2的幂.由迭代器直接访问. 下一个要用的 table;仅在扩容时非null 基本计数器值,主要在没有争用时使用,也用作table初始化竞争期间的反馈.通过CAS更新 table 初始化和扩容的控制 如果为负,则表将被初始化或扩容: -1用于初始化 -N 活动的扩容线程数 否则,当table为null时,保留创建时要使用的初始表大小,或者默认为0. 初始化后,保留下一个要扩容表的元素计数值. 扩容时要拆分的下一个表索引(加1)

阿里巴巴/招行信用卡中心21届实习面试知识点汇总

╄→гoц情女王★ 提交于 2020-04-20 01:43:45
基础 JDK1.8的新特性(阿里) ①引入了lambda表达式,可以简化匿名内部类的代码,允许将方法作为参数。②方法引用,可以进一步简化lambda表达式的书写,可以引用类的构造方法,静态方法,特定类的方法和某个对象的方法。③可以在接口中使用default定义默认方法和静态方法,引入默认方法方便了接口升级的维护,之前如果在接口中新增一个方法必须修改所有实现类。④引入了stream类,支持链式编程,为集合类和数组提供了一些方便的操作方法,例如filter、skip、limit和map、concat等。⑤可以通过类型自动推测泛型参数。⑥允许重复使用注解,扩大了注解的使用范围,可以用在局部变量和泛型,方法异常上。⑦引入了Optional类解决空指针异常,更新了日期类的API等。 HashMap的数据结构,源码原理,线程安全问题,红黑树 数据结构(招行) JDK1.8之前使用的是数组+链表的数据结构,每一个元素是一个Entry结点,包含key、value、hash值、指向下一个元素的next指针四个属性。JDK1.8之后使用的是数组+链表或红黑树的数据结构,每一个元素是一个Node结点,Node实现了Entry接口,Node有一个子类TreeNode,代表树结点。 源码原理(阿里) put方法: ①在存放数据时会先通过hash方法计算key的hashCode,JDK1.8之前的计算比较复杂

java锁机制的面试题

旧街凉风 提交于 2020-04-19 18:47:24
1、ABA问题 CAS 会导致“ABA问题”。 CAS 算法实现一个重要前提需要取出内存中某时刻的数据,而在下时刻比较并替换,那么在这个时间差类会导致数据的变化。 比如说一个线程 one 从内存位置 V 中取出 A,这时候另一个线程 two 也从内存中取出 A,并且 two 进行了一些操作变成了 B,然后 two 又将 V 位置的数据变成 A,这时候线程 one 进行 CAS 操作发现内存中仍然是 A,然后 one 操作成功。尽管线程 one 的 CAS 操作成功,但是不代表这个过程就是没有问题的。 部分乐观锁的实现是通过版本号(version)的方式来解决 ABA 问题,乐观锁每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行 +1 操作,否则就执行失败。因为每次操作的版本号都会随之增加,所以不会出现 ABA 问题,因为版本号只会增加不会减少。 2、CAS乐观锁 CAS 是项乐观锁技术,当多个线程尝试使用 CAS 同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。 CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作

《Java并发编程艺术》第二章Java并发机制的底层实现

♀尐吖头ヾ 提交于 2020-04-18 15:41:53
第一章Java并发挑战主要有: 上下文切换问题: 解决思路: 1.减少线程数量 2.增长线程内的有效利用率(就是线程运行时间和上下文切换时间) 死锁 解决思路: 1.避免一个线程同时获得多个锁 2.避免一个线程在锁内同时占用多个资源。 3.尝试使用定时锁(lock.tryLock(timeout)) 4.对数据库锁,保证操作由一个连接完成 资源限制 第二章: volatile 定义: 实现线程访问共享变量时,为了确保共享变量能够准确和一致的更新。 为何需要: 由于在默认的情况下,CPU发现一个操作数是可以进行缓存的便将其缓存下来 (缓冲行填充) ,若下次再访问该操作数所在地址时,则不通过内存访问,而是直接访问缓冲行中的值 (缓存命中) ,进行操作,再判断写入的地址是否已经存于缓存行,若是则将值再写到缓冲行 (写命中) 。 这样在多线程的场景下,就会影响问题,线程读到的时之前的数据,各做各的也没有达到目标。 如何解决: 这时变需要使用volatile变量了,它添加到某变量上时,就保证了CPU只能从内存读值且缓存行无效。 它会给原来的指令追加一条带 lock前缀 的指令,这个指令保证了两件事: 将当前处理器缓存行的数据写回系统内存(实现方式1.锁总线,2.锁缓存行,破坏了缓存一致性机制,所以迫使CPU写回内存) 写回内存的操作会使得其他CPU缓存的该内存地址的数据无效。(实现方式

Java并发编程系列-(8) JMM和底层实现原理

拜拜、爱过 提交于 2020-04-18 07:47:09
目前已经更新完《Java并发编程》,《Docker教程》和《JVM性能优化》,欢迎关注【后端精进之路】,轻松阅读全部文章。 <div align=center><img src="http://ww1.sinaimg.cn/large/a18449c6gy1gazysez0b1j20ni0n6afy.jpg" width = "200" height = "200"></div> Java并发编程: Java并发编程系列-(1) 并发编程基础 Java并发编程系列-(2) 线程的并发工具类 Java并发编程系列-(3) 原子操作与CAS Java并发编程系列-(4) 显式锁与AQS Java并发编程系列-(5) Java并发容器 Java并发编程系列-(6) Java线程池 Java并发编程系列-(7) Java线程安全 Java并发编程系列-(8) JMM和底层实现原理 Java并发编程系列-(9) JDK 8/9/10中的并发 Docker教程: Docker系列-(1) 原理与基本操作 Docker系列-(2) 镜像制作与发布 Docker系列-(3) Docker-compose使用与负载均衡 JVM性能优化: JVM性能优化系列-(1) Java内存区域 JVM性能优化系列-(2) 垃圾收集器与内存分配策略 JVM性能优化系列-(3) 虚拟机执行子系统 JVM性能优化系列

Mysql高手系列

邮差的信 提交于 2020-04-18 07:37:28
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能。 这是Mysql系列第20篇。 环境:mysql5.7.25,cmd命令中进行演示。 代码中被[]包含的表示可选,|符号分开的表示可选其一。 需求背景 我们在写存储过程的时候,可能会出现下列一些情况: 插入的数据违反唯一约束,导致插入失败 插入或者更新数据超过字段最大长度,导致操作失败 update影响行数和期望结果不一致 遇到上面各种异常情况的时,可能需要我们能够捕获,然后可能需要回滚当前事务。 本文主要围绕异常处理这块做详细的介绍。 此时我们需要使用游标,通过游标的方式来遍历select查询的结果集,然后对每行数据进行处理。 本篇内容 异常分类详解 内部异常详解 外部异常详解 掌握乐观锁解决并发修改数据出错的问题 update影响行数和期望结果不一致时的处理 准备数据 创建库: javacode2018 创建表:test1,test1表中的a字段为主键。 /*建库javacode2018*/ drop database if exists javacode2018; create database javacode2018; /*切换到javacode2018库*/ use javacode2018; DROP TABLE IF EXISTS test1; CREATE TABLE test1(a

Encoding problem with APEX app builder caused by CAS

三世轮回 提交于 2020-04-18 03:46:12
问题 I have a problem with APEX app builder/sql workshop for a while. There is a encoding issue (APEX must serve EastEuropean chars). Finnaly i found the source of the issue. I have implemented a CAS sso into APEX thru web.xml (APEX is on Tomcat/ORDS). Without CAS evrything is working fine, but i need it. Below there is the web.xml configuration. <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> <init-param>

单点登录(SSO)解决方案介绍

99封情书 提交于 2020-04-18 02:38:45
一、单点登录的介绍 单点登录(Single Sign On),简称为 SSO ,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 例如:百度旗下有很多的产品,比如百度贴吧、百度知道、百度文库等,只要登录百度账号,在任何一个地方都是已登录状态,不需要重新登录。 当用户第一次访问应用系统的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行校验,检查ticket的合法性。如果通过校验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。 、 要实现SSO,需要以下主要的功能: 所有应用系统共享一个身份认证系统。   统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。 所有应用系统能够识别和提取ticket信息   要实现SSO的功能,让用户只登录一次

都9012了,Java8日期时间API你还没有掌握?

六眼飞鱼酱① 提交于 2020-04-18 02:06:49
工作这么久了,对于Java中时间日期的操作一直很蛋疼,一会用Date,一会用Calendar一会用LocalDateTime,始终没有认真总结过它们的联系与区别。迷迷糊糊用了好几年了,今天终于搞清楚了! 一,Java8日期时间API产生的前因后果 1.1 为什么要重新定义一套日期时间API 操作不方便:java中最初的Date不能直接对 指定字段进行加减 操作也不支持 国际化 ,后来新增了Calendar,但是Calendar又不支持格式化操作,需要转换成Date再进行格式化,总之一直在填坑,使用起来一点都不够优雅。 线程不安全:Date,Caleandar,SimpleDateFormat都是可变的,线程不安全的,所以你需要编写额外的代码处理线程安全问题。 1.2 Java8重新定义 对时间日期相关操作进行细分:时间,日期,日期&时间,时间戳,时间段,日期段,格式化等 所有类都是不可变的,线程安全 兼容旧的日期时间 1.3Java8兼容旧版本的Date,同时也规范了日期时间的转换流程。 一,给人读的( LocalDateTime & LocalDate & LocalTime) java8中将时间和日期进行的区分,用LocalDateTime表示日期和时间,LocalDate用来表示日期而LocalTime表示时间。内部实现也非常好理解, LocalDateTime =

蘑菇街Java大牛纯手打肛出的一份多线程文档,请别丢进收藏夹吃灰

Deadly 提交于 2020-04-17 22:19:25
前言 这个【多线程】的文档是全程手打肛出来的,共129页,希望各位老铁可以转发本文支持一下! 完整版多线程文档资料领取方式:加我VX【tkzl6666】获得免费领取方式。领取之后可别丢进收藏夹吃灰喔! 内容介绍 一、什么是多线程 1.初识多线程 1.1介绍进程 1.2回到线程 1.3进程与线程 1.4并行与并发 1.5Java实现多线程 1.5.1继承Thread,重写run方法 1.5.2实现Runnable接口,重写run方法 1.6Java实现多线程需要注意的细节 二、Thread类解析 1.Thread线程类API 1.1设置线程名 1.2守护线程 1.3优先级线程 1.4线程生命周期 1.4.1sleep方法 1.4.2yield方法 1.4.3join方法 1.4.3interrupt方法 三、使用多线程需要注意的问题 1、使用多线程遇到的问题 1.1线程安全问题 1.3性能问题 2、对象的发布与逸出 2.1安全发布对象 3、解决多线程遇到的问题 3.1简述解决线程安全性的办法 3.2原子性和可见性 3.2.1原子性 3.2.2可见性 3.3线程封闭 3.4不变性 3.5线程安全性委托 4、多线程需要注意的事 -总结 四、synchronized锁和lock锁 1、synchronized锁 1.1synchronized锁是什么? 1