[TOC]一、日期转换的问题1.1 问题提出下面的代码在运行时,由于 SimpleDateFormat 不是线程安全的import lombok.extern.slf4j.Slf4j; import java.text.ParseException; import java.text.SimpleDateFormat; /** * @author lilinchao * @date 2022-11-11 * @description 日期转换的问题 **/ @Slf4j(topic = "c.Test07") public class Test07 { ...
[TOC]前一段时间在研究juc源码的时候,发现在很多工具类中都调用了一个Unsafe类中的方法,出于好奇就想要研究一下这个类到底有什么作用,于是先查阅了一些资料,一查不要紧,很多资料中对 Unsafe 的态度都是这样的画风:其实看到这些说法也没什么意外,毕竟 Unsafe 这个词直译过来就是“不安全的”,从名字里我们也大概能看来 Java 的开发者们对它有些不放心。但是作为一名极客,不能你说不安全我就不去研究了,毕竟只有了解一项技术的风险点,才能更好的避免出现这些问题嘛。下面我们言归正传,先通过简单的介绍来对 Unsafe 类有一个大致的了解。Unsafe 类是一个位于sun.misc...
[TOC]一、原子累加器对比我们通过如下代码,比较synchronized、AtomicInteger、AtomicLong、LongAdder、LongAccumulator五种计数性能。示例需求:热点商品点赞计算器,点赞数进行统计,不要求实时精确。50个线程,每个线程100W次,统计总点赞数。import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import ...
[TOC]一、概述前面所讲的几个原子更新引用类型如:AtomicReference,用于整个对象的更新。但不是每次都必须更新整个对象,有可能我们只需对对象中的某个字段进行原子性修改时,那么就需要使用原子更新字段类。在java.util.concurrent.atomic中,原子类型字段更新器有以下三种:AtomicIntegerFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定int类型字段。AtomicLongFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定long类型字段。AtomicReferenceFieldUpdater:基于反...
[TOC]一、数组类型的原子类原子数组类型,这个其实和AtomicInteger等类似,只不过在修改时需要指明数组下标。CAS是按照==来根据地址进行比较。数组比较地址,肯定是不行的,只能比较下标元素。而比较下标元素,就和元素的类型有关系了。在java.util.concurrent.atomic中,原子类型数组有以下四种:类名说明AtomicIntegerArray提供对int[]数组元素的原子性更新操作AtomicLongArray提供对long[]数组元素的原子性更新操作AtomicReferenceArray提供对引用类型[]数组元素的原子性更新操作AtomicBooleanAr...
[TOC]一、概述为什么需要原子引用类型?保证引用类型的共享变量是线程安全的。基本类型原子类只能更新一个变量,如果需要原子更新多个变量,需要使用引用类型原子类。AtomicReference:引用类型原子类;AtomicStampedRerence:原子更新带有版本号的引用类型;该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。AtomicMarkableReference :原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题...
[TOC]前言AtomicInteger 类底层存储一个int值,并提供方法对该int值进行原子操作。AtomicInteger 作为java.util.concurrent.atomic包的一部分,从Java 1.5开始引入。接下来我们先从三个问题入手,对AtomicInteger概念有一个基本的了解。一、概述(1)什么是原子操作呢?所谓原子操作,就是一个独立且不可分割的操作。AtomicInteger 工具类提供了对整数操作的原子封装。(2)为什么要对整数操作进行原子封装呢?在 java 中,当我们在多线程情况下,对一个整型变量做加减操作时,如果不加任何的多线程并发控制,大概率会出现...
[TOC]一、案例分析前面看到的 AtomicInteger 的解决方法,内部并没有用锁来保护共享变量的线程安全。那么它是如何实现的呢?public void withdraw(Integer amount) { // 需要不断尝试,直到成功为止 while (true) { // 比如拿到了旧值 1000 int prev = balance.get(); // 在这个基础上 1000-10 = 990 int next = prev - amount...
[TOC]一、引述需求:保证多线程情况下 account.withdraw 取款方法的线程安全import java.util.ArrayList; import java.util.List; /** * @author lilinchao * @date 2022-11-03 * @description 取款方法 **/ public interface Account { //获取余额 Integer getBalance(); //取款 void withdraw(Integer amount); /** * 方法内会...