多线程技术内容片段

读写锁跟互斥锁类似,也是申请锁的时候,如果不能得到满足则阻塞,但读写锁跟互斥锁也有不同,读写锁有3个状态:已加读锁状态已加写锁状态未加锁状态对应3个状态,读写锁有3个接口:加读锁,加写锁,解锁:加读锁:如果读写锁处于已加写锁状态,则申请锁的线程阻塞;否则把锁设置为已加读锁状态并成功返回加写锁:如果读

ThreadLocal的一些缺陷

概述本文主要讲述了ThreadLocal存储的一些缺陷,以及如何通过其他办法弥补这些缺陷。ThreadLocal的缺陷首先ThreadLocal的缺陷其实是因为开放定址法解决哈希冲突这种方式导致的。这种解决冲突的方式的优点是实现简单,对于key不多的情况下,性能也不存在问题。但是当数据量多起来(当然

ConcurrentHashMap笔记

插入元素的时候的加锁操作插入元素的时候会通过tryLock尝试获取锁,如果获取失败那么会进入自旋状态,直到自旋的次数达到阈值,这时候会通过lock方法进行阻塞当前线程。扩容的时候的lastRun是什么意思lastRun代表着这个链表从最后的一个节点开始往上直到计算idx不一样的为止。这个目的是为了加

ThreadPool源码分析

ThreadPoolExecutorThreadPoolExecutor 是 JDK 中的线程池实现,这个类实现了一个线程池需要的各个方法,它实现了任务提交、线程管理、监控等等方法。我们可以基于它来进行业务上的扩展,以实现我们需要的其他功能,比如实现定时任务的类 ScheduledThreadPoo

AQS各种锁获取和释放流程梳理

概述AQS中获取锁和释放锁有两种模式:独占锁独占锁获取的流程:1、获取锁失败(tryAcquire返回false)先加入到阻塞队列中2、循环获取同步状态获取不到就挂起,直到被唤醒抢占头节点并继续执行。独占锁释放的流程:1、释放锁成功(tryRelease返回true)2、判断head节点不为空,并且

如何优化多线程上下文切换

如果是单个线程,在 CPU 调用之后,那么它基本上是不会被调度出去的。如果可运行的线程数远大于 CPU 数量,那么操作系统最终会将某个正在运行的线程调度出来,从而使其它线程能够使用 CPU ,这就会导致上下文切换。还有,在多线程中如果使用了竞争锁,当线程由于等待竞争锁而被阻塞时,JVM 通常会将这个

Stream的一些内容

官方将 Stream 中的操作分为两大类:中间操作(Intermediate operations)和终结操作(Terminal operations)。中间操作只对操作进行了记录,即只会返回一个流,不会进行计算操作,而终结操作是实现了计算操作。中间操作又可以分为无状态(Stateless)与有状态

LongAdder源码

前言并发场景下通常会使用 AtomicLong 原子类进行计数等操作,在 JDK1.8 中提供了 LongAdder 来实现类似功能。相对于 AtomicLong ,LongAdder 有着更高的性能,可以完全替代 AtomicLong 的计数操作。下面我们先对 AtomicLong 简单介绍,然后

CopyOnWriteArrayList源码分析

前言ArrayList 是一个非线程安全集合,需要使用方自行处理线程安全问题,或者使用 Collections.synchronizedList 包装。从 JDK 1.5 开始 JUC 中提供了使用写时复制机制实现的并发容器 CopyOnWriteArrayList。概述CopyOnWriteArr