![](https://img-blog.csdnimg.cn/20190920151839436.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java杂货铺
TheLudlows
这个世界上还有什么比自己写的代码运行在一亿的电脑上更酷的事情吗,如果有那就是让这个数字再扩大十倍。
展开
-
Java并发编程:延时任务队列的实现原理
优先级队列DelayedWorkQueueDelayedWorkQueue用来存放将要执行的任务,其数据结构为有序二叉堆。有序二叉堆的特点:所有根结点必定不大于其两个叶子节点任意结点的子节点的索引位置是其本身索引位置乘2后+1任意结点的父节点的索引位置是该结点的索引位置-1后除2并向下取整当新添加元素时,加入到数组的尾部,后面我们结合代码分析添加过程DelayedWorkQueu...原创 2019-04-03 09:49:55 · 1936 阅读 · 0 评论 -
Java并发编程系列:深入分析AQS原理
文章目录数据结构定义获取锁# Lock.lock -> Sync.lock# AQS.acquire -> Sync.tryAcquire# addWaiter# acquireQueued释放锁lockInterruptiblyCondition实现原理AQS又称为队列同步器,它是用来构建锁或其他同步组件的基础框架,它是实现ReentrangLock、Semaphore等同步工具的...原创 2019-03-20 19:06:54 · 413 阅读 · 0 评论 -
Java并发编程系列:Synchronized原理解析
#从对象头的说起https://blog.csdn.net/TheLudlows/article/details/75340361 文章中介绍了对象的内存布局。如上图所示,Mark Word 存储对象自身的运行时数据如哈希值等,例如对象的hashCode、GC分代年龄、锁状态标志、线程持有的锁、偏向线程的ID、偏向时间戳等。Mark Word一般被设计为非固定的数据结构,以便存储更多的数据...原创 2019-03-19 00:05:20 · 400 阅读 · 0 评论 -
Java并发编程系列:漫谈伪共享
文章目录1. CPU缓存2. CPU缓存一致性协议2.1 局部性原理2.2 Cache Line2.3 cache的写方式2.4 一致性协议MESI3. 伪共享4. 复现伪共享伪共享的非标准定义为:缓存系统中是以缓存行(cache line)为单位存储的,当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享下面我们就来详细剖析伪共享产生的前因后...原创 2018-11-21 19:32:43 · 935 阅读 · 0 评论 -
Java并发编程系列:ThreadPoolExecutor源码分析
1. 线程池的状态线程池有五种状态,定义在ThreadPoolExecutor中。// runState is stored in the high-order bits//可以接受新的任务,也可以处理阻塞队列里的任务private static final int RUNNING = -1 << COUNT_BITS;//不接受新的任务,但是可以处理阻塞队列原创 2018-11-19 00:00:26 · 206 阅读 · 0 评论 -
Java Magic:Unsafe
Unsafe(sun.misc.Unsafe)是jdk中自带的一个类,因为是在sun.misc包下,所以一般也不建议直接使用,同时Unsafe提供了一组底层(low-level)、unsafe的操作。Unsafe类注释中也有这样一段描述:虽然该类及所有方法都是公开的,但使用该类是有限的,因为只有受信任的代码才能获得它的实例。1.获取Unsafe实例Unsafe对象不能直接通过构造函数...原创 2018-09-10 00:17:12 · 721 阅读 · 0 评论 -
Java并发编程系列:CyclicBarrier
偏向锁与轻量级锁理念上的区别:轻量级锁:在无竞争的情况下使用CAS操作去消除同步使用的互斥量 偏向锁:在无竞争的情况下把整个同步都消除掉,连CAS操作都不做了轻量级锁轻量级锁(Lightweight Locking)本意是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗,是为了减少多线程进入互斥的几率,并不是要替代互斥。在代码进入同步块的时候,如果此同步对象没有被锁定(原创 2017-09-28 11:26:21 · 363 阅读 · 0 评论 -
Java并发编程系列:CountDownLatch
闭锁(Latch)闭锁CountDownLatch唯一的构造方法CountDownLatch(int count),当在闭锁上调用countDown()方法时,闭锁的计数器将减1,当闭锁计数器为0时,闭锁将打开,所有线程将通过闭锁开始执行。CountDownLatch是JDK 5+里面闭锁的一个实现,允许一个或者多个线程等待某个事件的发生。CountDownLatch有一个正数计数器,countDo原创 2017-09-28 11:10:53 · 552 阅读 · 0 评论 -
Java并发编程系列:FutureTask源码解读
Future模式概述Future模式是一种常见的设计模式,它的核心思想是异步调用,当调用一个函数方法时,如果方法执行非常慢,但我们又不急着需要结果,因此我们可以让被调用者立即返回,让他在后台慢慢处理,对于调用者来说可以先处理一些其他的任务,当真正需要数据时尝试获得需要的数据。 Future模式无法立即给出需要的数据,但是他会返回一个契约,将来凭借着这个锲约去重新获取结果。CallableCalla原创 2017-08-09 10:50:01 · 598 阅读 · 1 评论 -
Java并发编程系列:ThreadLocal源码分析
1.ThreadLocal的小例子ThreadLoca它是一个线程的局部变量,也就是说只有当前线程可以访问,他肯定是线程安全的。 ThreadLocal的主要应用场景为按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。例如:同一个网站登录用户,每个用户服务器会为其开一个线程,每个线程中创建一个ThreadLocal,里面存用户基本信息等,在很多页面跳转时,会显示用户信原创 2017-08-09 10:36:10 · 360 阅读 · 0 评论 -
Java并发编程系列:线程池原理详解
为什么需要线程池线程是轻量级的进程,但其创建和关闭人需要话费时间,如果每一个小任务都创建一个线程,很有可能出现创建和销毁线程所占用的时间大于该线程处理任务所需的时间。因此合理的创建和使用线程至关重要。然而线程池能做到这点。线程池的定义和连接池类似,线程池中有创建好的线程,当需要时直接从池子中拿空闲的线程。当完成工作室,把线程放回线程池中。JDK对线程池的支持它们均在java.util.concurr原创 2017-08-09 10:27:31 · 507 阅读 · 0 评论 -
Java并发编程系列:并发容器
并发容器集合简介JDK提供的这些容器大部分在java.util.concurrent包中。ConcurrentHashMap:高效并发HashMap。CopyOnWriteArrayList:适合读多写少的情况ConcurrentLinkedQueue:高效并发队列,使用列表实现,可以看做一个线程安全的LinkedListBlockingQueue:这是一个接口,表示阻塞队列Concurr原创 2017-08-09 10:22:57 · 287 阅读 · 0 评论 -
Java并发编程系列:锁优化
单核的并行算法的效率要低于原始串行的算法,因为并行多线程多了线程调度、上下文切换等开销。而单线程器主要资源都花在 任务本身,他不需要维护数据结构的一致性,也不需要为线程的切换和调度花费时间。并行计算之所以能提高系统的性能,而是因为他更合理的进行任务调度,充分利用各个CPU的资源,合理的并发,才能将CPU的性能发挥到极致。在高并发的环境下,激烈的所竞争会导致程序的性能下降。1.减少锁的持有时间在必要时原创 2017-08-09 10:17:19 · 383 阅读 · 0 评论 -
Java并发编程系列:CAS 详解
什么是无锁?无锁是一种乐观的策略,它会假设资源的访问时没有冲突的,没有冲突则不需要等待,所有的线程都可以在不停顿的状态下执行,如果遇到冲突,使用比较交换的技术(CAS)重试当前的操作直到没有冲突为止。CAS(比较交换)CAS算法过程:它包含三个参数CAS(v,e,n),v表示需要更新的变量,e表示预期的值,n表示新值,仅当v等于e时,才会将v的值设置为n。如果v值和e值不同,则说明已有其他线程做了更原创 2017-08-09 09:59:09 · 605 阅读 · 0 评论 -
Java并发编程系列:ReentrantReadWriteLock
读写所ReadWriteLockJDK1.5提供读写分离锁,读写分离锁可以有效的减少锁竞争,以提升系统性能。比如:线程A1、A2、A3进行读操作,B1、B2、B3进行写操作,如果是重入锁或者内部锁,所有的读之间,读写之间和写写之间都是串行操作,如B1进行读取时,B2、B3需要等待锁。由于读操作并不对数据完整性造成破坏,因此这种等待是没有意义的。所以就有了读写锁。 读写所允许多个线程同时读,但是写写原创 2017-08-09 09:56:34 · 318 阅读 · 0 评论 -
Java并发编程系列:Semaphore
允许多个线程同事访问:信号量(Semaphore)无论是内部锁synchroized还是重入锁RentrantLocky,一次只允许一个线程访问资源,而信号量却可以指定多个线程同事访问一个资源。public Semaphore(int permits) 创建具有给定的许可数和非公平的公平设置的 Semaphore。 public Semaphore(int permits,原创 2017-08-09 09:54:15 · 255 阅读 · 0 评论 -
Java并发编程系列:ReentrantLock
重入锁重入锁使用java.util.concurrent.locks.ReentrantLock类来实现。其性能优于synchronized。ReentrantLock增加了一些高级功能级功能等待可中断:在synchronized中,如果一个线程在等待锁,他只用两种结果,要么获得锁执行完,要么一直保持等待。可中断得等待是通知正在等待的线程,告诉他没必要再等待后。实现公平锁:公平锁:会按照时间的先原创 2017-08-09 09:50:49 · 517 阅读 · 0 评论 -
浅析Java8 Stream原理
文章目录操作符的分类流水线的结构AbstractPipelineStream的生成源码分析添加中间操作万事俱备,只欠东风上一篇文章中大体的介绍了Stream的概念和基本API的使用,Stream用起来的确非常的爽。这一片文章将会讲述Stream的底层实现原理。操作符的分类,Stream中的操作可以分为两大类:中间操作与结束操作,中间操作只是对操作进行了记录,只有结束操作才会触发实际的计算(即...原创 2018-12-03 20:27:57 · 4350 阅读 · 0 评论 -
异步编程 CompletableFuture详解
文章目录1. CompletableFuture概述2. How to use2.1 创建CompletableFuture2.2 获取结果2.3 转换操作2.4 组合操作2.5 完成时处理2.6 异常处理1. CompletableFuture概述在异步编程中,Future/Promise模式是一种广泛使用的异步开发模式,其中 Future 对象代表一个尚未完成异步操作的结果。从JDK 1....原创 2018-11-29 18:57:01 · 1354 阅读 · 0 评论 -
Java8:Stream详解
Stream是什么?官方解释:Stream是元素的集合,这点让Stream看起来用些类似Iterator;可以支持顺序和并行的对原Stream进行汇聚的操作;Stream好比一个高级版本的Iterator,在Iterator中,我们只能一个一个的遍历元素并对其执行操作,而在Stream中只需要给出具体的操作,比如过滤”J”开头的字母的字符串,去掉长度大于10的字符串,八折一系列的操作给Stre原创 2017-12-12 16:04:32 · 476 阅读 · 0 评论 -
NIO之终极Selctor源码分析
回顾一下Selector,多路复用器Selector可以管理多个Channel,可以向Selector注册感兴趣的事件,当事件就绪,通过Selector.selector方法获取注册的事件,进行相应的操作。Selector selector = Selector.open();ServerSocketChannel serverSocketChannel = ServerSocketChann...原创 2018-10-03 14:03:10 · 1021 阅读 · 1 评论 -
Reactor模型的Java NIO实现
之前写的Reactor模型文章只是最基本的单线程模式,此外还有两种基于多线程的Reactor模型,分别为单线程模型和单Reactor多线程模型和多Reactor多线程模型。下面分别介绍。1.单线程模型因为之前的文章就是此类型,在此只介绍一种简单的实现。Server端public class Reactor1 { public static void main(Stri...原创 2018-07-20 17:43:39 · 3828 阅读 · 7 评论 -
IO多路复用之Select/Poll和Epoll
select原理概述调用select时,会发生以下事情: 1.select()机制中提供一fd_set的数据结构,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄(不管是socket句柄,还是其他文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一socket原创 2017-10-06 14:10:46 · 1268 阅读 · 0 评论 -
NIO之Reactor模式
NIO与Reactor模式Reactor是一种广泛应用在服务器端开发的设计模式。那么Reactor模式究竟是个什么东西呢?传统IO首先得说一说经典的网络服务的设计 对于应用服务器,一个主要规律就是,CPU的处理速度是要远远快于IO速度的,如果CPU为了IO操作(例如从Socket读取一段数据)而阻塞显然是不划算的。好一点的方法是分为多进程或者线程去进行处理,但是这样会带来一些进程切换的开销。但原创 2017-09-16 20:31:32 · 1049 阅读 · 0 评论 -
浅析I/O模型
IO模型有四种1.阻塞IO(Blocking IO)2.非阻塞IO(Non-blocking IO)3.IO多路复用(IO Multiplexing):经典的Reactor设计模式,也称为异步阻塞IO,java中Selector和linux中的epoll。4.异步IO:经典的Proactor设计模式,也称为异步非阻塞IO。同步和异步的概念描述的是用户线程与内核的交互方式:同步是指用户线程发起IO请原创 2017-09-15 09:39:08 · 914 阅读 · 0 评论 -
JVM系列:对象的实例化过程
1. Java对象创建时机2. Java 对象的创建过程2.1 实例变量初始化2.2 构造函数初始化3. 小结1. Java对象创建时机一个对象在可以被使用之前必须要被正确地实例化。在Java代码中,有很多行为可以引起对象的创建。下面对各种方式一一介绍。1.1使用new关键字创建对象这是我们最常见的也是最简单的创建对象的方式,通过这种方式我们...原创 2018-09-09 19:58:24 · 1147 阅读 · 0 评论 -
Thread类源码分析
文章目录Thread状态构造方法启动startjoin方法interrupt方法总结Thread状态Thread内部有个State枚举,标示着线程的状态。public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;}NEW 状态是指线程刚创...原创 2018-10-02 23:44:36 · 251 阅读 · 0 评论 -
并行框架Fork/Join原理解析
概述Java 1.7 引入了一种新的并发框架—— Fork/Join Framework。这个框架使用的场景就是将一个大任务按照意愿切分成N个小任务并行执行,并最终聚合结果,加快运算。这里的执行指的是多任务同时在多个线程中并行。,这里说的是并行,而不是并发并行是指系统内有多个任务同时执行,而并发是指系统内有多个任务同时存在,不同的任务按时间分片的方式切换执行,给人的感觉好像是在同时执行。Fo...原创 2018-11-20 23:56:22 · 1348 阅读 · 0 评论 -
JVM系列:JIT技术概述
1. Java中字节码、机器指令字节码是指平常所了解的 .class 文件,通过 javac 命令编译成字节码。机器指令是指机器可以直接识别运行的代码,字节码是不能直接运行的,JVM 通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译才能运行。很显然逐条的解释其执行速度必然会比可执行的二进制字节码程序慢很多,这是传统的JVM的解释器(Interpreter)的功能。为了提高执行速度...原创 2019-02-18 00:02:37 · 1129 阅读 · 0 评论 -
JMH:Java微基准测试框架
Measure it , Don’t guess!当我们写代码的时候总会遇到一些选择上的困惑,比如数据库连接池Druid和HikariCP到底哪一个效率更高,或者是LinkedList和ArrayList哪个在特定的场景下更快,再比如找到系统性能的瓶颈所在,但是具体是哪个方法哪条语句执行太慢而导致的。不要猜,请测试它。上面提到的场景都可以通过JMH(ava Microbenchmark H...原创 2019-03-12 16:22:20 · 995 阅读 · 0 评论 -
JVM系列:Java内存模型
1. java内存模型java虚拟机规范想定义一种java内存模型(jmm),来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能达到一致的内存访问效果。 java内存模型主要定义了程序中各个变量的访问规则,即变量到内存的存入和读取。此处的变量不局部变量。因为局部变量是线程私有的,不会被共享。 Java内存模型规定了所有的变量都存储在主内存,每个线程都有自己的工作内存(原创 2017-07-26 09:02:58 · 517 阅读 · 0 评论 -
JVM系列:JVM类加载详解
1. 类加载的过程加载、验证、准备、解析、初始化、使用、卸载2. 加载2.1 流程通过一个类的全限定名来获取定义此类的二进字制节流。将二进制字节流所代表的静态存储结构转化为方法区的运行时数据结构。在内存中生成一个代表这个类的Class对象,作为这个类的访问入口。(实在方法区中)2.2 数组的加载数组类本身不需要类加载器创建,它是由Java虚拟机直接创建。而非数组类可以由系统提供的类加载器来完原创 2017-07-21 15:24:33 · 340 阅读 · 0 评论 -
JVM系列:GC总结
1.回收的区域我们知道,虚拟机栈、程序计数器和本地方法栈都是随线程生,随线程灭。线程结束时,内存也就自然释放了。但是Java堆和方法区则不一样,这部分内存的分配和回收都是动态的,所以垃圾回收期关注的就是这部分区域。2.判断对象能否被回收的算法有两种方法:引用计数算法和可达性分析算法2.1 引用计数算法给每一个对象添加一个计数器,每当有一个引用指向它时,计数器加一。当计引用失效时,计数器减一。如果一个原创 2017-07-19 17:16:54 · 390 阅读 · 0 评论 -
JVM系列:虚拟机中的对象布局
1.对象的创建创建一个对象(克隆、反序列化)通常通过一个new关键字。那它到底是个什么过程呢? 虚拟机遇到一条new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析、初始化,如果没有,则进行相应得类加载过程。 类加载检查通过后,接下来为新生对象分配内存。 内存分配完成之后,虚拟机将分配的内存空间都初始化为零值(不原创 2017-07-19 10:31:12 · 660 阅读 · 0 评论 -
JVM系列:Java运行时数据区域
Java运行时数据区域1.1 程序计数器程序计数器是一块比较小的内存空间。他可以看作是当前线程所执行的字节码的行好指示器。在虚拟机的概念模型里,字节码的解释器工作就是改变这个计数器的值来选取下一条字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。多线程中计数器的作用java中多线程是通过线程轮流切换并分配处理器的执行时间的方式来实现的,在一个时刻,一个处理器只会执原创 2017-07-18 11:09:41 · 450 阅读 · 0 评论 -
Java垃圾收集器概述
Parallel Scavenge收集器特性: Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器。应用场景: 停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验,而高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。对比分析:Parallel Scavenge收集原创 2017-09-21 11:14:45 · 419 阅读 · 0 评论 -
谈谈JDK堆外内存的创建和回收
堆外内存的优势在于IO操作,相比堆内存可以减少一次copy和gc的次数。下面通过源码去了解堆外内存的分配和回收。一般分配堆外内存通过ByteBuffer allocateDirect(int capacity)方法,其内部是通过如下构造函数来实现。DirectByteBuffer(int cap) { super(-1, 0, cap, cap);// ma...原创 2019-09-20 15:14:57 · 543 阅读 · 1 评论 -
谈谈Java Reference的原理
ReferenceReference是所有引用类型的父类,它与垃圾回收器合作来来进行GC,Reference类定义了子类的主要逻辑,所以在SoftReference、WeakReference和PhantomReference中几乎完全复用了Reference的逻辑。下面进入Reference类中进行分析它的原理。构造函数和属性其中一个构造函数可以传入一个队列,如果不传入那么使用默认的队...原创 2019-09-19 21:34:30 · 428 阅读 · 0 评论 -
深入分析CMS垃圾收集器原理
文章目录CMS相关参数触发条件周期性GC主动触发收集过程注意事项前文已经讲过,CMS是老年代垃圾收集器,在收集过程中可以与用户线程并发操作。它可以与Serial收集器和Parallel New收集器搭配使用。CMS牺牲了系统的吞吐量来追求收集速度,适合追求垃圾收集速度的服务器上。CMS相关参数触发条件周期性GC主动触发由后台线程ConcurrentMarkSweepThread循环判断...原创 2019-06-20 23:47:47 · 2718 阅读 · 2 评论