Java Core
xiaofang233
开源互联网技术追随者、狂热者。
展开
-
可重入锁ReentrantLock源码分析
# 什么是可重入锁可重入锁是指一个线程获得了锁之后仍然可以反复的加锁,不会出现自己阻塞自己的情况。# 锁类型ReentrantLock 分为公平锁和非公平锁,可以通过构造方法来指定具体类型:```java //默认非公平锁 public ReentrantLock() { sync = new NonfairSync(); } //公平锁 public ReentrantLock(boolean fair) { s原创 2020-10-07 02:40:32 · 165 阅读 · 0 评论 -
一道老生常谈的字符串对象创建问题
问题和结论老生常谈的一个问题,String s = new String(“abc”)创建了几个对象,String s = "abc"又是创建了几个对象?先说结论:String s = new String(“abc”)创建了1个或2个对象,String s = "abc"创建了一个或0个对象接下来我们探究一下String s = new String(“abc”) 和String s = "abc"创建过程的区别。String s = new String(“abc”)的创建过程系统先在字符原创 2020-10-03 17:46:42 · 275 阅读 · 0 评论 -
ArrayList源码分析—基于JDK8
# ArrayList概述1. ArrayList 是一种变长的集合类,基于定长数组实现。2. ArrayList 允许空值和重复元素,当往 ArrayList 中添加的元素数量大于其底层数组容量时,其会通过扩容机制重新生成一个更大的数组。3. 由于 ArrayList 底层基于数组实现,所以其可以保证在 O(1) 复杂度下完成随机查找操作。4. ArrayList 是非线程安全类,并发环境下,多个线程同时操作 ArrayList,会引发不可预知的异常或错误。原创 2020-09-04 13:23:48 · 119 阅读 · 0 评论 -
AtomicInteger原子操作分析
原子类在编程领域里,原子性意味着“一组操作要么全都操作成功,要么全都失败,不能只操作成功其中的一部分”。而 java.util.concurrent.atomic 下的类,就是具有原子性的类,可以原子性地执行添加、递增、递减等操作。比如之前多线程下的线程不安全的 i++ 问题,到了原子类这里,就可以用功能相同且线程安全的 getAndIncrement 方法来优雅地解决。原子类的作用和锁有类似之处,是为了保证并发情况下线程安全。不过原子类相比于锁,有一定的优势:粒度更细:原子变量可以把竞争范围缩小到原创 2020-08-24 12:17:23 · 480 阅读 · 0 评论 -
延迟队列DelayQueue用法
DelayQueue介绍我们首先介绍一下DelayQueue,DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的Delayed 元素。DelayQueue使用场景和用法DelayQueue阻塞队列在我们系统开发中也常常会用到,例如:缓存系统的设计,缓存中的对象,超过了空闲时间,需要从缓存中移出;任务调度系统,能够准确的把握任务的执行时间。我们可能需要通过线程处理很多时间上要求很严格的数据,如果使用普通的线程,我们就需要遍历所有的对象,一个一原创 2020-08-21 20:32:02 · 709 阅读 · 0 评论 -
阻塞队列介绍以及在线程池中的应用
> BlockingQueue 接口的实现类都被放在了 J.U.C 包中,包括ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue,以及DelayQueue。# 阻塞队列介绍## ArrayBlockingQueue先从最基础的 ArrayBlockingQueue 说起。ArrayBlockingQueue 是最典型的有界队列,其内部是用数组存储元素的,利用 ReentrantLock 实现线原创 2020-08-21 17:43:13 · 311 阅读 · 0 评论 -
CopyOnWriteArrayList源码分析
CopyOnWriteArrayListJDK1.5 开始,Java 并发包里提供了使用 CopyOnWrite 机制实现的并发容器CopyOnWriteArrayList 作为主要的并发 List,CopyOnWrite 的并发集合还包括 CopyOnWriteArraySet,其底层也是利用 CopyOnWriteArrayList 实现的。适用场景读操作可以尽可能的快,而写即使慢一些也没关系在很多应用场景中,读操作可能会远远多于写操作。比如,有些系统级别的信息,往往只需要加载或者修改很少的原创 2020-08-20 22:56:24 · 158 阅读 · 0 评论 -
Java常量池理解
Java 的内存分配中,总共 3 种常量池,分别是:全局字符串池(string pool)、class 文件常量池(class constant pool)、运行时常量池(runtime constant pool)什么是常量用 final 修饰的成员变量表示常量,值一旦给定就无法改变final 修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。全局字符串池(string pool)字符串常量池在 Java 内存区域的哪个位置在 JDK6.0 及之前版本,字符串常.原创 2020-08-19 10:49:03 · 222 阅读 · 0 评论 -
ThreadLocal内存泄漏分析
什么是内存泄漏内存泄漏指的是,当某一个对象不再有用的时候,占用的内存却不能被回收,这就叫作内存泄漏。因为通常情况下,如果一个对象不再有用,那么我们的垃圾回收器 GC,就应该把这部分内存给清理掉。这样的话,就可以让这部分内存后续重新分配到其他的地方去使用;否则,如果对象没有用,但一直不能被回收,这样的垃圾对象如果积累的越来越多,则会导致我们可用的内存越来越少,最后发生内存不够用的 OOM 错误。下面我们来分析一下,在 ThreadLocal 中这样的内存泄漏是如何发生的。...原创 2020-08-17 21:51:47 · 94 阅读 · 0 评论 -
手撕代码—两个线程交替打印1 -- 100
方案一: synchronized + wait/notifypublic class TwoThreadPrint { private static Object object = new Object(); private static boolean isFlag = false; public static void main(String[] args) { new Thread(() -> { for (int i = 1原创 2020-08-17 19:32:40 · 129 阅读 · 0 评论 -
AQS内部原理分析以及在CountDownLatch中的应用
> 分析CountDownLatch之前先看下AQS,它是并发包中锁和同步器的底层实现,所以理解AQS的工作原理是很有必要的。# AQS的工作原理AQS 最核心的三大部分就是**状态、队列和期望协作工具类去实现的获取/释放等重要方法**。我们就从这三个部分出发,分别展开讲解。## state 状态第一个要讲解的是状态 state,如果我们的 AQS 想要去管理或者想作为协作工具类的一个基础框架,那么它必然要管理一些状态,而这个状态在 AQS 内部就是用 state 变量去表示的。它的定义如下:原创 2020-08-17 11:33:25 · 293 阅读 · 1 评论 -
Scala高阶函数和Java 8 Lambda表达式
Scala 高阶函数高阶函数(Higher-Order Function)就是操作其他函数的函数。Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果。以下实例中,apply() 函数使用了另外一个函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v:object Test { def main(args: Array[String]) { println( apply( layout, 10) ) } // 函数 f原创 2020-08-14 11:33:55 · 184 阅读 · 0 评论 -
线程池中线程复用原理
线程复用原理我们知道线程池会使用固定数量或可变数量的线程来执行任务,但无论是固定数量或可变数量的线程,其线程数量都远远小于任务数量,面对这种情况线程池可以通过线程复用让同一个线程去执行不同的任务,那么线程复用是如何实现的呢?...原创 2020-08-12 20:13:17 · 1828 阅读 · 0 评论 -
synchronized底层原理和锁优化
# synchronized底层原理众所周知 synchronized 关键字是解决并发问题常用解决方案,有以下三种使用方式:- 同步普通方法,锁的是当前对象。- 同步静态方法,锁的是当前 Class 对象。- 同步块,锁的是 () 中的对象。实现原理:JVM 是通过进入、退出对象监视器( Monitor )来实现对方法、同步块的同步的。具体实现是在编译之后在同步方法调用前加入一个 monitor.enter 指令,在退出方法和异常处插入 monitor.exit 的指令。其本质原创 2020-08-11 17:29:22 · 286 阅读 · 0 评论 -
阻塞/非阻塞队列线程安全剖析
我们将ArrayBlockingQueue和ConcurrentLinkedQueue作为阻塞/非阻塞队列的代表,来剖析一下并发队列线程安全的原理。# ArrayBlockingQueue线程安全剖析我们首先看一下 ArrayBlockingQueue 的源码,ArrayBlockingQueue 有以下几个重要的属性:```java// 用于存放元素的数组final Object[] items;// 下一次读取操作的位置int takeIndex;// 下一次写入操作的位置int原创 2020-08-10 19:47:23 · 363 阅读 · 0 评论 -
ConcurrentHashMap在JDK1.7和JDK1.8的实现对比
Java 8 中,对于 ConcurrentHashMap 这个常用的工具类进行了很大的升级,对比之前 Java 7 版本在诸多方面都进行了调整和变化。Java 7 版本的 ConcurrentHashMapJava 8 版本的 ConcurrentHashMap原创 2020-08-05 10:20:31 · 456 阅读 · 0 评论 -
HashMap源码研究
HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等。本文结合JDK1.7和JDK1.8的区别,深入探讨HashMap的结构实现和功能原理。简介Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap、Hashtable、LinkedHashMap和TreeMa..原创 2020-08-05 10:15:38 · 189 阅读 · 0 评论 -
探究JDK7 HashMap并发扩容导致CPU100%原因
HashMap之所以在并发下的扩容造成死循环,是因为,**多个线程并发进行时,因为一个线程先期完成了扩容,将原的链表重新散列到自己的表中,并且链表变成了倒序,后一个线程再扩容时,又进行自己的散列,再次将倒序链表变为正序链表。于是形成了一个环形链表。**当调用get操作并命中链环的桶时,就会进入一个死循环的情况,将CPU的消耗到100%。...原创 2020-05-15 17:34:30 · 1000 阅读 · 1 评论