自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(14)
  • 收藏
  • 关注

原创 使用ArrayBlockingQueue实现一个生产者消费者模型

提供一个demo,仅供参考public class ArrayBlockingQueueTestService { // 自定义线程池 static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2000, 5000, 100, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(1000

2022-05-22 09:47:35 417

原创 ScheduledThreadPoolExecutor实现延时及定时任务的步骤

ScheduledThreadPoolExecutor提供的两个方法来完成延迟及定时执行任务scheduleAtFixedRate及scheduleWithFixedDelay大致执行步骤:1)创建task任务2)将任务加入到延迟队列3)启用线程通过getTask方法从队列中获取任务4)延迟队列中的take方法获取任务时,会根据等待时间阻塞任务;针对scheduleAtFixedRate源码分析:public ScheduledFuture<?> schedul

2022-05-21 20:04:20 3272

原创 BlockingQueue各实现队列及主要方法

1、LinkedBlockQueue和ArrayBlockingQueue的区别1)数据结构不同ArrayBlockingQueue内部是通过一个数组实现的;LinkedBlockQueue内部是通过一个单向链表实现的;2)锁机制不同ArrayBlockingQueue中只有一把锁,无法实现读写分离;LinkedBlockQueue中有两把锁,一把takeLock,一把putLock,读写互不干扰,可 实现读写分离;3)构造方法不同ArrayBlockingQueue创建时必

2022-05-21 19:58:03 411

原创 线程池execute执行流程源码分析

在分析源码之前需要先介绍一些基本概念:线程池的几种创建方法及线程池中一些重要变量,有基础的可以跳过,直接从第3步开始看源码分析。1、线程池主要有四种创建方方法: Executor提供的三种静态方法:// 使用核心线程及同步队列,效率高,但是消耗CPUExecutorService cachedThreadPool = Executors.newCachedThreadPool();// 使用指定线程数及链表队列,效率不太高,大量并发会造成内存溢出ExecutorService f...

2022-05-12 17:11:38 661

原创 使用newCondition方法+ReentranLock实现本地队列

直接给一个demo吧package com.dxd.demo.service;import com.dxd.demo.pojo.Eat;import com.dxd.demo.pojo.GetUp;import com.dxd.demo.pojo.Sleep;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.loc.

2022-05-07 12:19:18 447

原创 ReentrantReadWriteLock读写锁的lock、unlock源码分析

先说一下结论,再分析源码,ReentrantReadWriteLock拆分了两把锁,一把读锁ReadLock,一把写锁WriteLock,读锁是共享的,写锁是独占的;也就是说,如果有线程在读,其他线程也可以读,但是不能写;如果有线程在写,则其他线程不能读也不能写。lockReadLock一、tryAcquireShared 获取共享锁先来看第一个方法tryAcquireShared获取共享锁主要分四部分,介绍这四部分之前先来介绍一点东西,AQS里边只有一个state来记录锁的

2022-05-06 23:17:53 628 2

原创 ReentrantLock的lock、unlock源码分析

一、lock可以看出加锁方法主要有这三步,最后那个selfInterrupt方法是中断线程,里边就一行代码中断线程,这里就不展开说了。先简单说一下这三步:1:通过CAS方式尝试获取锁2:获取锁失败的情况下,为当前线程创建node节点,加入到队列末尾3:加入队列后,判断前一节点是不是head节点,是的话尝试去获取锁;上一节点不是head节点,或获取锁失败,就将上一个节点的waitStatus改为-1,意思是告诉上一节点,你释放完锁后需要通知我,然后将自己线程park掉。1:tr..

2022-05-05 12:25:33 316

原创 AtomicInteger、AtomicLong、LongAdder的性能问题及源码分析

1、AtomicInteger这里主要看incrementAndGet方法可以看出,AtomicInteger的累加方法使用了unsafe中的getAndAddInt方法(这里的U是jdk.internal.misc.Unsafe类)AtomicInteger之所以使用unsafe进行数据累加而不适用volatile,就是因为volatile不能保证数据的原子性,而unsafe可以。我们看到,unsafe中的累加方法是通过CAS实现的,多线程并发时,同时只会有一个修改成功,其它的线程会

2022-05-04 13:27:21 1693

原创 hashmap为什么在链表长度大于8,且数组长度大于64时将链表转换为红黑树

这个问题分两步分析:1、为什么是链表长度大于8时看一下源码解释就是官方做过很多测试,发现链表长度在大于8以后再出现hash碰撞的可能性几乎为0,虽然转化为红黑树后,查找的效率会比链表高,但是转化红黑树这个过程是耗时的,而且在扩容时还要对红黑树重新的左旋右旋保持平衡,相对耗时,所以,阈值设置为8就是为了尽量减少hashmap中出现红黑树(hashmap中链表才是常态)2、为什么数组长度大于64时同样,先看一下源码怎么解释的其实这个源码中解释的不清不楚,里边说最小应该为4*.

2022-04-30 22:46:16 7458 2

原创 hashmap为什么采用两倍扩容

我们先来看看源码中官方是怎么解释的红线标注意思大概就是:以二次幂展开,容器的元素要么保持原来的索引,要么以二次幂的偏移量出现在新表中。也就是说hashmap采用2倍扩容,可以尽可能的减少元素位置的移动。看下图(不考虑链表的情况)可以看出,数组初始长度为2的幂次方,随后以2倍扩容的方式扩容,元素在新表中的位置要么不动,要么有规律的出现在新表中(二的幂次方偏移量),这样会使扩容的效率大大提高。另外,hashmap采用二倍扩容还有另外一个好处:可以使元素均匀的散布hashmap中,减少

2022-04-30 21:53:39 8209

原创 hashmap1.7头插法造成死循环的原因分析

关于这个问题,网上的说法真是五花八门,怎么说的都有,我也不知道他们是不是真的理解。我是对照源码一步步分析的,目前为止,我只看到一个视频和我的观点是一样的,大家不同意的可以自己去扒源码自己分析一遍,至少我的答案按照源码分析是没有出入的。首先说结论:hashmap1.7中的死循环问题并不是发生在并发写入过程,而是发生在get请求中,并发写入只可能形成环状链表;其次,环状链表是几个节点相互指向,不是某个节点自己指向自己。分析:首先上源码:void transfer(Entry[] newTabl

2022-04-26 00:43:47 6163 11

原创 AQS和CAS粗略介绍

1、AQS是什么:全称 abstractQueuedSynchronizer,一个抽象类,队列同步器。常见的实现有ReentrantLock、ReadWriteLock有什么用:构建锁、释放锁、同步队列。怎么实现:先看AQS中的重要参数:head:记录队列中头部节点tail:记录队列中尾部节点state:记录队列中等待访问线程数量,通过volatile关键字修饰,保证该参数对所有参数可见且有序(就是有序访问,针对于内存上)note内部类:一个双向队列thread:当前占用

2022-04-17 20:28:33 1330

原创 HashMap和concurrentHashMap的区别

1、HashMap 非线程安全数据结构:数组 + 链表(不懂没关系,下边画图解释)entity0 entity1 .... entity(n-2) entity(n-1)

2022-04-16 13:19:31 10916

原创 ArrayList、LinkedList和CoypOnWriteArrayList的区别

1、ArrayList 非线程安全,当定义成员变量时需考虑高并发时的线程安全问题。数据结构:Object数组,存储在连续的内存空间上。性能问题:查询:由于数组在内存上的存储空间是连续的,因此查询性能高,可以通过角标索引直接定位到元素,时间复杂度O(1);但是新增和删除性能不高,为什么呢?删除:假设删除了元素3,那么删除后后边的元素都需要左移,时间复杂度O(n);1 2 3 4 5 6 7 添加:如果数组内空间不足,插入元素时会触发A

2022-04-10 22:22:00 713

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除