05 2018 档案

摘要:前言 楼主今天在面经上看到这个题,挺有意思,小小的题目对多线程的考量还挺多。大部分同学都会使用 synchronized 来实现。楼主今天带来另外两种优化实现,让你面试的时候,傲视群雄! 第一种 synchronized 我们通过使用 CAS,避免线程的上下文切换,然后呢,使用一个 volatile 阅读全文
posted @ 2018-05-26 00:55 莫那-鲁道 阅读(24121) 评论(12) 推荐(6) 编辑
摘要:前言 让我们继续探秘 Java 热部署。在前文 "探秘 Java 热部署二(Java agent premain)" 中,我们介绍了 Java agent premain。通过在main方法之前通过类似 AOP 的方式添加 premain 方法,我们可以在类加载之前做修改字节码的操作,无论是第一次加 阅读全文
posted @ 2018-05-20 00:03 莫那-鲁道 阅读(16983) 评论(1) 推荐(0) 编辑
摘要:楼主学习 JVM 总结的知识点,用思维脑图串起来,温故而知新,其中含有类加载器,内存布局,GC(右侧)。 最多的就是 GC 的内容了。 内容有错误之处,还请指正。 "大图地址" 阅读全文
posted @ 2018-05-20 00:03 莫那-鲁道 阅读(1504) 评论(0) 推荐(0) 编辑
摘要:前言 在之前的 "深入浅出 JVM ClassLoader" 一文中,我们说可以通过修改默认的类加载器实现热部署,但在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作。对于 阅读全文
posted @ 2018-05-20 00:02 莫那-鲁道 阅读(2598) 评论(1) 推荐(0) 编辑
摘要:前言 在前文 "探秘 Java 热部署" 中,我们通过在死循环中重复加载 ClassLoader 和 Class 文件实现了热部署的功能,但我们也指出了缺点 不够灵活。需要手动修改文件等操作。 如果有那么一种功能,当你需要重新加载类并修改类的时候,有那么一个转换器自动帮你修改已有的 Class 文件 阅读全文
posted @ 2018-05-20 00:02 莫那-鲁道 阅读(4425) 评论(0) 推荐(1) 编辑
摘要:前言 从前面的3篇文章中,我们分析了5个垃圾收集器,还有一些 GC 的算法,那么,在 GC 调优中,我们肯定会先判断哪里出现的问题,然后再根据出现的问题进行调优,而调优的手段就是 JVM 提供给我们的那些参数或者说选项,这些参数将会改变 GC 的运行方式。因此,他们显得极为重要。 我们将每一个垃圾收 阅读全文
posted @ 2018-05-20 00:01 莫那-鲁道 阅读(4292) 评论(0) 推荐(1) 编辑
摘要:前言 在 JVM 综述里面,我们说,JVM 做了三件事情,Java 程序的内存管理, Java Class 二进制字节流的加载(ClassLoader),Java 程序的执行(执行引擎)。我们也说,我们大部分情况下只关注前2个。在前面的文章中,我们已经分析了内存关系相关的,包括运行时数据区,GC 相 阅读全文
posted @ 2018-05-20 00:01 莫那-鲁道 阅读(453) 评论(0) 推荐(0) 编辑
摘要:前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的。各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题。楼主同样也遇到过这些问题,那么,遇到这些问题该如何解决呢? 首先,出现问题,肯定要先定位问题所在,然后分析问题原因,再然后解决问题,最后进行总结,防止 阅读全文
posted @ 2018-05-20 00:01 莫那-鲁道 阅读(2264) 评论(0) 推荐(5) 编辑
摘要:前言 在 "深入浅出 JVM GC(2)" 中,我们介绍了一些 GC 算法,GC 名词,同时也留下了一个问题,就是每个 GC 收集器的具体作用。有哪些 GC 收集器呢? 1. Serial 串行收集器(只适用于堆内存 256M 以下的 JVM ) 2. ParNew 并行收集器(Serial 收集器 阅读全文
posted @ 2018-05-20 00:00 莫那-鲁道 阅读(672) 评论(0) 推荐(0) 编辑
摘要:前言 在 "深入浅出 JVM GC(1)" 中,限于上篇文章的篇幅,我们留下了一个问题 : 如何回收? 这篇文章将重点讲述这个问题。 在上篇文章中,我们也列出了一些大纲,今天我们就按照那个大纲来逐个讲解。在此,我将大纲复制过来。 垃圾回收算法 1. 标记清除算法 2. 复制算法 3. 标记整理算法 阅读全文
posted @ 2018-05-19 23:59 莫那-鲁道 阅读(420) 评论(0) 推荐(0) 编辑
摘要:前言 初级 Java 程序员步入中级程序员的有一个无法绕过的阶段 GC(Garbage Collection)。作为 Java 程序员,说实话,很幸福,不用像 C 程序员那样,时刻关心着内存,就像网上有句名言 生活从来都不容易,只不过是有人替你负重前行! 是的,GC 在替我们做这些脏活累活,GC 像 阅读全文
posted @ 2018-05-19 23:58 莫那-鲁道 阅读(425) 评论(0) 推荐(1) 编辑
摘要:引自《深入理解Java 虚拟机》 前言 JVM 运行时数据分为几大部分 1. 程序计数器 2. Java 虚拟机栈 3. 本地方法栈 4. Java 堆 5. 方法区(永久代) 6. 运行时常量池 7. 直接内存 JVM 内存区域 Java 虚拟机在执行Java 程序的过程中会把它所管理的内存划分为 阅读全文
posted @ 2018-05-19 23:57 莫那-鲁道 阅读(524) 评论(0) 推荐(0) 编辑
摘要:概览 从 JVM 的总体上看,它解决了3个问题: 1. Java 程序的内存管理(GC & 运行时数据区)。 2. Java Class 二进制字节流的加载(ClassLoader)。 3. Java 程序的执行(执行引擎)。 如下图所示: 在我们的日常开发中,最和我们息息相关的就是1和2了,比如 阅读全文
posted @ 2018-05-19 23:56 莫那-鲁道 阅读(495) 评论(0) 推荐(2) 编辑
摘要:目录: 1. dubbo 的 Consumer 消费者如何使用 Netty 2. dubbo 的 Provider 提供者如何使用 Netty 3. 总结 前言 众所周知,国内知名框架 Dubbo 底层使用的是 Netty 作为网络通信,那么内部到底是如何使用的呢?今天我们就来一探究竟。 1. du 阅读全文
posted @ 2018-05-19 23:55 莫那-鲁道 阅读(12163) 评论(3) 推荐(4) 编辑
摘要:前言 我们知道,Java 创建一个实例的消耗是不小的,如果没有使用栈上分配和 TLAB,那么就需要使用 CAS 在堆中创建对象。所以现在很多框架都使用对象池。Netty 也不例外,通过重用对象,能够避免频繁创建对象和销毁对象带来的损耗。 来看看具体实现。 1. Recycler 抽象类简介 该类 d 阅读全文
posted @ 2018-05-19 23:54 莫那-鲁道 阅读(1813) 评论(0) 推荐(1) 编辑
摘要:前言:Netty 提供的心跳介绍 Netty 作为一个网络框架,提供了诸多功能,比如我们之前说的编解码,Netty 准备很多现成的编解码器,同时,Netty 还为我们准备了网络中,非常重要的一个服务 心跳机制。通过心跳检查对方是否有效,这在 RPC 框架中是必不可少的功能。 Netty 提供了 Id 阅读全文
posted @ 2018-05-19 23:54 莫那-鲁道 阅读(977) 评论(0) 推荐(0) 编辑
摘要:Netty 解码器抽象父类 ByteToMessageDecoder 源码解析 阅读全文
posted @ 2018-05-19 23:53 莫那-鲁道 阅读(914) 评论(0) 推荐(0) 编辑
摘要:前言 在 "Netty 源码剖析之 unSafe.read 方法" 一文中,我们研究了 read 方法的实现,这是读取内容到容器,再看看 Netty 是如何将内容从容器输出 Channel 的吧。 1. ctx.writeAndFlush 方法 当我们调用此方法时,会从当前节点找上一个 outbou 阅读全文
posted @ 2018-05-19 23:51 莫那-鲁道 阅读(573) 评论(0) 推荐(0) 编辑
摘要:目录: 1. NioSocketChannel$NioSocketChannelUnsafe 的 read 方法 2. 首先看 ByteBufAllocator 3. 再看 RecvByteBufAllocator.Handle 4. 两者如何配合进行内存分配 5. 如何读取到 ByteBuf 6. 阅读全文
posted @ 2018-05-19 23:50 莫那-鲁道 阅读(1016) 评论(0) 推荐(0) 编辑
摘要:目录: 前言 1. ChannelOutboundBuffer 介绍 2. addMessage 方法 3. addFlush 方法 4. flush0 方法 5. 缓冲区扩展思考 6. 总结 每个 ChannelSocket 的 Unsafe 都有一个绑定的 ChannelOutboundBuff 阅读全文
posted @ 2018-05-19 23:50 莫那-鲁道 阅读(7123) 评论(0) 推荐(2) 编辑
摘要:前言 对于堆外内存,使用 System.gc() 是不靠谱的,依赖老年代 FGC 也是不靠谱的,而且大部分调优指南都设置了 DisableExplicitGC 禁用 System.gc()。所以主动回收比较靠谱, JDK 在 DirectByteBuffer 中提供了 Cleaner 用来主动释放内 阅读全文
posted @ 2018-05-19 23:49 莫那-鲁道 阅读(2756) 评论(0) 推荐(0) 编辑
摘要:目录大纲: 1. 前言 2. 处理耗时业务的第一种方式 handler 种加入线程池 3. 处理耗时业务的第二种方式 Context 中添加线程池 4. 总结:两种方式的对比和思考 前言 熟悉 Netty 的同学都知道,不能在 Netty 中做耗时的,不可预料的操作,比如数据库,网络请求,这将会严重 阅读全文
posted @ 2018-05-19 23:48 莫那-鲁道 阅读(4811) 评论(0) 推荐(0) 编辑
摘要:目录大纲: 0. 前言 1. ChannelPipeline | ChannelHandler | ChannelHandlerContext 三巨头介绍 2. 三巨头编织过程(创建过程) 3. ChannelPipeline 是如何调度 handler 的 4. 总结 前言 相信对 Netty 熟 阅读全文
posted @ 2018-05-19 23:47 莫那-鲁道 阅读(740) 评论(0) 推荐(0) 编辑
摘要:目录大纲: 1. 前言 2. 针对 Netty 例子源码做了哪些修改? 3. 看 pipeline 是如何将数据送到自定义 handler 的 4. 看 pipeline 是如何将数据从自定义 handler 送出的 5. 总结 前言 在 "Netty 核心组件 Pipeline 源码分析(一)之剖 阅读全文
posted @ 2018-05-19 23:47 莫那-鲁道 阅读(617) 评论(0) 推荐(0) 编辑
摘要:前言 在前文 "Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)" 中,我们分析了整个服务器端的启动过程。在那篇文章中,我们重点关注了启动过程,而在启动过程中对核心组件并没有进行详细介绍,比如 EventLoop ,Pipeline,Unsafe 等。实际上,Netty 的大部分组 阅读全文
posted @ 2018-05-19 23:46 莫那-鲁道 阅读(1240) 评论(3) 推荐(2) 编辑
摘要:前言 Netty 作为高性能框架,对 JDK 中的很多类都进行了封装了和优化,例如 Thread 类,Netty 使用了 FastThreadLocalRunnable 对所有 DefaultThreadFactory 创建出来的 Runnable 都进行了包装。包装的目的是 run 方法的不同,看 阅读全文
posted @ 2018-05-19 23:46 莫那-鲁道 阅读(1220) 评论(2) 推荐(1) 编辑
摘要:前言 在前文中,我们分析了服务器是如何启动的。而服务器启动后肯定是要接受客户端请求并返回客户端想要的信息的,否则要你服务器干啥子呢?所以,我们今天就分析分析 Netty 在启动之后是如何接受客户端请求的。 开始吧! 1. 从源头开始 从之前服务器启动的源码中,我们得知,服务器最终注册了一个 Acce 阅读全文
posted @ 2018-05-19 23:45 莫那-鲁道 阅读(2771) 评论(0) 推荐(0) 编辑
摘要:前言 作为一个 Java 程序员,必须知道Java社区最强网络框架 Netty,且必须看过源码,才能说是了解这个框架,否则都是无稽之谈。今天楼主不会讲什么理论和概念,而是使用debug 的方式,走一遍 Netty (服务器)的启动过程。 1. demo 源码 楼主 clone 的 netty 的源码 阅读全文
posted @ 2018-05-19 23:44 莫那-鲁道 阅读(1806) 评论(1) 推荐(1) 编辑
摘要:前言 在分布式系统中,常常需要使用缓存,而且通常是集群,访问缓存和添加缓存都需要一个 hash 算法来寻找到合适的 Cache 节点。但,通常不是用取余hash,而是使用我们今天的主角—— 一致性 hash 算法。 今天楼主就来说说这个一致性 hash 算法。 1. 为什么普通的 hash 算法不行 阅读全文
posted @ 2018-05-19 23:42 莫那-鲁道 阅读(1683) 评论(0) 推荐(1) 编辑
摘要:前言 在前文 "分布式理论(八)—— Consistent Hash(一致性哈希算法)" 中,我们讨论了一致性 hash 算法的原理,并说了,我们会自己写一个简单的算法。今天就来写一个。 普通 hash 的结果 先看看普通 hash 怎么做。 首先,需要缓存节点对象,缓存中的存储对象,还有一个缓存节 阅读全文
posted @ 2018-05-19 23:42 莫那-鲁道 阅读(638) 评论(0) 推荐(0) 编辑
摘要:1. 服务框架的设计 尽管不同的分布式服务框架实现细节存在差异,但是核心功能差异不大,下面的架构图描绘了一个分布式服务框架的整体逻辑架构。 总共分为 3 层: 1. 服务层,Service,其中主要部分就是动态代理,主要用于将服务提供者的接口封装成远程服务调用。上层的服务接口用于 Spring 之类 阅读全文
posted @ 2018-05-19 23:42 莫那-鲁道 阅读(2045) 评论(0) 推荐(0) 编辑
摘要:前言 我们说为了实现 BASE 理论,需要在可用性和一致性之间找到一个合适的一致性理论,于是,我们在上篇文章中了解了 2PC 理论,也就是两阶段提交,二阶段提交原理简单,实现方便,但是缺点则是同步阻塞,单点问题,数据不一致,过于保守。 而为了弥补二阶段提交的缺点,研究者们在他的基础上,提出了三阶段提 阅读全文
posted @ 2018-05-19 23:41 莫那-鲁道 阅读(5230) 评论(1) 推荐(0) 编辑
摘要:前言 Paxos 算法如同我们标题大图:世界上只有一种一致性算法,就是 Paxos。出自一位 google 大神之口。 同时,Paxos 也是出名的晦涩难懂,推理过程极其复杂。楼主在尝试理解 Paxos 算法的过程中历经挫折。 今天,楼主不会讲推理过程,因为就算是尝试使用大白话来讲,也非常的难懂。当 阅读全文
posted @ 2018-05-19 23:41 莫那-鲁道 阅读(3322) 评论(0) 推荐(2) 编辑
摘要:前言 我们之前讲述了 Paxos 一致性算法,虽然楼主尝试用最简单的算法来阐述,但仍然还是有点绕。楼主最初怀疑自己太笨,后来才直到,该算法的晦涩难懂不是只有我一个人这么认为,而是国际公认! 所以 Paxos 算法在 1990 就发表出来,但却得不到运用。真正的名声大噪还是在兰伯特使用 “更简单” 的 阅读全文
posted @ 2018-05-19 23:41 莫那-鲁道 阅读(2888) 评论(1) 推荐(2) 编辑
摘要:前言 在前面的文章中,我们说了很多一致性协议,比如 Paxos,Raft,2PC,3PC等等,今天我们再讲一种协议,ZAB 协议,该协议应该是所有一致性协议中生产环境中应用最多的了。为什么呢?因为他是为 Zookeeper 设计的分布式一致性协议! 1. 什么是 ZAB 协议? ZAB 协议介绍 1 阅读全文
posted @ 2018-05-19 23:41 莫那-鲁道 阅读(26595) 评论(14) 推荐(14) 编辑
摘要:前言 在前文 "分布式理论(一) —— CAP 定理" 中,我们说,CAP 不可能同时满足,而分区容错是对于分布式系统而言,是必须的。最后,我们说,如果系统能够同时实现 CAP 是再好不过的了,所以出现了 BASE 理论,今天就来讲讲 Base 理论。 1. 什么是 Base 理论 BASE:全称: 阅读全文
posted @ 2018-05-19 23:40 莫那-鲁道 阅读(12011) 评论(2) 推荐(3) 编辑
摘要:前言 为了使系统尽量能够达到 CAP,于是有了 BASE 协议,而 BASE 协议是在可用性和一致性之间做的取舍和妥协。 人们往往需要在系统的可用性和数据一致性之间反复的权衡。于是呢,就产生我们标题中的一致性协议,而且还不止一个呢。 为了解决分布式问题,涌现了很多经典的算法和协议,最著名的就是二阶段 阅读全文
posted @ 2018-05-19 23:40 莫那-鲁道 阅读(3686) 评论(0) 推荐(0) 编辑
摘要:目录: 1. 什么是 CAP 定理 2. 为什么只能 3 选 2 3. 能不能解决 3 选 2 的问题 4. 引用 1. 什么是 CAP 定理 2000 年的时候,Eric Brewer 教授提出了 CAP 猜想,2年后,被 Seth Gilbert 和 Nancy Lynch 从理论上证明了猜想的 阅读全文
posted @ 2018-05-19 23:39 莫那-鲁道 阅读(4701) 评论(3) 推荐(3) 编辑
摘要:前言 每一次总结都意味着重新开始,同时也是为了更好的开始。ConcurrentHashMap 一直是我心中的痛。虽然不敢说完全读懂了,但也看了几个重要的方法,有不少我觉得比较重要的知识点。 然后呢,放一些楼主写的关于 ConcurrentHashMap 相关源码分析的文章链接: 1. "Concur 阅读全文
posted @ 2018-05-19 23:28 莫那-鲁道 阅读(692) 评论(1) 推荐(0) 编辑
摘要:前言 楼主自1月14号就停更了,这段时间一直在看JVM,因此没有更新任何文章,但楼主觉得有必要总结一下之前学习并发的过程,因为这一次的总结其实就是下一次的开始。主要时总结一下并发的学习路线,因为在楼主的工作环境中,并不是每天都在编写高并发的程序。然而,即使是这样,我们也要知道并发的每个知识点,这样才 阅读全文
posted @ 2018-05-19 23:28 莫那-鲁道 阅读(308) 评论(0) 推荐(0) 编辑
摘要:前言 ConcurrentHashMap 精华代码很多,前面分析了 helpTransfer 和 transfer 和 putVal 方法,今天来分析一下 addCount 方法,该方法会在 putVal 方法中调用。 该方法可以配合 size 方法一起查看,关于该方法,楼主也写了一篇文章分析过: 阅读全文
posted @ 2018-05-19 23:27 莫那-鲁道 阅读(569) 评论(0) 推荐(1) 编辑
摘要:前言 这是一篇对 transfer 方法的拾遗,关于之前那篇文章的一些一笔带过,或者当时不知道的地方进行回顾。 疑点 1. 为什么将链表拆成两份的时候,0 在低位,1 在高位? 回顾一下 transfer 的相关代码: 关键看上面注释的代码,如果 runBit 是 0,那么就设置在低位节点,反之,如 阅读全文
posted @ 2018-05-19 23:27 莫那-鲁道 阅读(2144) 评论(0) 推荐(0) 编辑
摘要:前言 ConcurrentHashMap 是并发中的重中之重,也是最常用的数据结果,之前的文章中,我们介绍了 putVal 方法。 "并发编程之 ConcurrentHashMap(JDK 1.8) putVal 源码分析" 。其中分析了 initTable 方法和 putVal 方法,但也留下了一 阅读全文
posted @ 2018-05-19 23:25 莫那-鲁道 阅读(2276) 评论(2) 推荐(2) 编辑
摘要:前言 ConcurrentHashMap 鬼斧神工,并发添加元素时,如果 map 正在扩容,其他线程甚至于还会帮助扩容,也就是多线程扩容。就这一点,就可以写一篇文章好好讲讲。今天一起来看看。 源码分析 为什么帮助扩容? 在 putVal 方法中,如果发现线程当前 hash 冲突了,也就是当前 has 阅读全文
posted @ 2018-05-19 23:24 莫那-鲁道 阅读(698) 评论(0) 推荐(0) 编辑
摘要:前言 RPC 服务中,每个服务的容量都是有限的,即资源有限,只能承受住给定的网络请求,所以,在设计 RPC 框架的时候,一定要考虑流量控制这个问题。而 Java 中,实现流量控制有很多中方式,今天说 2 种。 Semaphore 实现流控 代码: 这段代码和上面的类似,只是使用的 API 不同,这里 阅读全文
posted @ 2018-05-19 23:23 莫那-鲁道 阅读(949) 评论(0) 推荐(0) 编辑
摘要:前言 如何中断一个线程,肯定不会使用 stop。而是使用 interrupt 方法。同时,我们知道,中断一个线程只是打个标志位。不会真的中断线程,但,如果线程是阻塞状态的呢? 而 Java 中,想要阻塞一个线程有很多种方式。 1. synchronized 2. Object.wait() 3. L 阅读全文
posted @ 2018-05-19 23:23 莫那-鲁道 阅读(291) 评论(0) 推荐(0) 编辑
摘要:1. 前言 Java 中总的算起来有 8 种阻塞队列。 我们分析了: "并发编程之 SynchronousQueue 核心源码分析" "并发编程之 ConcurrentLinkedQueue 源码剖析" "并发编程之 LinkedBolckingQueue 源码剖析" 在 "并发编程 —— Sche 阅读全文
posted @ 2018-05-19 23:22 莫那-鲁道 阅读(4057) 评论(0) 推荐(2) 编辑
摘要:参考 :梁飞 "并发编程常识" 阅读全文
posted @ 2018-05-19 23:22 莫那-鲁道 阅读(522) 评论(0) 推荐(0) 编辑
摘要:关于 Java 内存模型的类似思维导图。 如有错误,还请指正。 阅读全文
posted @ 2018-05-19 23:22 莫那-鲁道 阅读(329) 评论(0) 推荐(0) 编辑
摘要:1. 前言 在前面的文章中,我们介绍了定时任务类 Timer ,他是 JDK 1.3 中出现的,位于 java.util 包下。而今天说的 的是在 JUC 包下,是 JDK1.5 新增的。 今天就来说说这个类。 2. API 介绍 该类内部结构和 还是有点类似的,也是 3 个类: :程序员使用的接口 阅读全文
posted @ 2018-05-19 23:21 莫那-鲁道 阅读(323) 评论(0) 推荐(0) 编辑
摘要:前言 在平时的开发中,肯定需要使用定时任务,而 Java 1.3 版本提供了一个 java.util.Timer 定时任务类。今天一起来看看这个类。 1.API 介绍 Timer 相关的有 3 个类: Timer :面向程序员的API 都在这个类中。 TaskQuue: 存储任务。 TimerThr 阅读全文
posted @ 2018-05-19 23:20 莫那-鲁道 阅读(403) 评论(0) 推荐(0) 编辑
摘要:1. 前言 在前面的文章 "并发编程之——写锁源码分析" 中,我们分析了 1.8 JUC 中读写锁中的 写锁的获取和释放过程 ,今天来分析一下读锁的获取和释放过程,读锁相比较写锁要稍微复杂一点,其中还有一点有争议的地方——锁降级。 今天就来解开迷雾。 2. 获取读锁 tryAcquireShared 阅读全文
posted @ 2018-05-19 23:18 莫那-鲁道 阅读(806) 评论(0) 推荐(0) 编辑
摘要:1. 前言 当我们在 Java 中使用异步编程的时候,大部分时候,我们都会使用 Future,并且使用线程池的 submit 方法提交一个 Callable 对象。然后调用 Future 的 get 方法等待返回值。而 FutureTask 是 Future 的一个实现,也是我们今天的主角。 我们就 阅读全文
posted @ 2018-05-19 23:18 莫那-鲁道 阅读(271) 评论(0) 推荐(0) 编辑
摘要:1. 前言 在并发编程中,异步回调的效率不言而喻,在业务开发中,如果由阻塞的任务需要执行,必然要使用异步线程。并且,如果我们想在异步执行之后,根据他的结果执行一些动作。 JDK 8 之前的 Future 只能解决上面需求的一半问题,即异步执行,返回一个 Future,需要程序员调用 get 方法等待 阅读全文
posted @ 2018-05-19 23:16 莫那-鲁道 阅读(348) 评论(0) 推荐(0) 编辑
摘要:1.前言 Java 中的读写锁实现是 ReentrantReadWriteLock ,是一种锁分离策略。能有效提高读比写多的场景下的程序性能。 关于如何使用参见 "并发编程之 Java 三把锁" 。 由于读写锁较为复杂,故分为篇文章进行源码分析,今天先说较为简单的写锁。 2. 写锁介绍 不论是读锁还 阅读全文
posted @ 2018-05-19 23:16 莫那-鲁道 阅读(254) 评论(1) 推荐(1) 编辑
摘要:前言 ConcurrentHashMap 博大精深,从他的 50 多个内部类就能看出来,似乎 JDK 的并发精髓都在里面了。但他依然拥有体验良好的 API 给我们使用,程序员根本感觉不到他内部的复杂。但,他内部的每一个方法都复杂无比,就连 size 方法,都挺复杂的。 今天就一起来看看这个 size 阅读全文
posted @ 2018-05-19 23:14 莫那-鲁道 阅读(8681) 评论(0) 推荐(3) 编辑
摘要:前言 ReentrantLock 提供了公平锁和非公平锁,只需要在构造方法中使用一个 参数即可。默认非公平锁。 今天从源码层面看看区别和具体实现。 1. 类 UML 图 内部有一个抽象类 ,继承了 AQS。 而公平锁的实现就是 ,非公平锁的实现就是 。 两把锁的区别在于 方法的实现。 2. 公平锁 阅读全文
posted @ 2018-05-19 23:13 莫那-鲁道 阅读(649) 评论(0) 推荐(0) 编辑
摘要:1. 从 acquire 方法开始 —— 获取 2. 为什么 AQS 需要一个虚拟 head 节点 3. reelase 方法如何释放锁 4. 总结 前言 AQS 是 JUC 中的核心,其中封装了资源的获取和释放,在我们之前的 "并发编程之 AQS 源码剖析" 文章中,我们已经从 ReentranL 阅读全文
posted @ 2018-05-19 23:12 莫那-鲁道 阅读(1172) 评论(0) 推荐(0) 编辑
摘要:前言 并发 JUC 包提供了很多工具类,比如之前说的 CountDownLatch,CyclicBarrier ,今天说说这个 Semaphore——信号量,关于他的使用请查看往期文章 "并发编程之 线程协作工具类" ,今天的任务就是从源码层面分析一下他的原理。 源码分析 如果先不看源码,根据以往我 阅读全文
posted @ 2018-05-19 23:11 莫那-鲁道 阅读(309) 评论(0) 推荐(0) 编辑
摘要:前言 JUC 包中除了 CountDownLatch, CyclicBarrier, Semaphore, 还有一个重要的工具,只不过相对而言使用的不多,什么呢? Exchange —— 交换器。用于在两个线程之间交换数据,A 线程将 a 数据交给 B 线程,B 线程将 b 数据交给 a 线程。 具 阅读全文
posted @ 2018-05-19 23:11 莫那-鲁道 阅读(185) 评论(0) 推荐(0) 编辑
摘要:前言 在之前的介绍 CountDownLatch 的文章中,CountDown 可以实现多个线程协调,在所有指定线程完成后,主线程才执行任务。 但是,CountDownLatch 有个缺陷,这点 JDK 的文档中也说了:他只能使用一次。在有些场合,似乎有些浪费,需要不停的创建 CountDownLa 阅读全文
posted @ 2018-05-19 23:10 莫那-鲁道 阅读(199) 评论(0) 推荐(0) 编辑
摘要:前言 从之前的阻塞队列的源码分析中,我们知道,JDK 中的阻塞队列是使用 ReentrantLock 和 Condition 实现了,我们今天来个简易版的。代码如下: 代码 其实,这并不是我写的,而是 Condition 接口的 JavaDoc 文档中写的。并且文档中说,请不要再次实现这个队列,因为 阅读全文
posted @ 2018-05-19 23:09 莫那-鲁道 阅读(1374) 评论(0) 推荐(0) 编辑
摘要:前言 Condition 是 Lock 的伴侣,至于如何使用,我们之前也写了一些文章来说,例如 "使用 ReentrantLock 和 Condition 实现一个阻塞队列" , "并发编程之 Java 三把锁" , 在这两篇文章中,我们都详细介绍了他们的使用。今天我们就来深入看看源码实现。 构造方 阅读全文
posted @ 2018-05-19 23:09 莫那-鲁道 阅读(306) 评论(0) 推荐(0) 编辑
摘要:前言 Doug Lea 大神在 JUC 包中为我们准备了大量的多线程工具,其中包括 CountDownLatch ,名为 ,好像不太好理解。不过,今天的文章之后,我们就彻底理解了。 如何使用? 在 JDK 的文档中,带有 2 个例子,我们使用其中一个,测试代码如下: await 方法调用的是 Syn 阅读全文
posted @ 2018-05-19 23:08 莫那-鲁道 阅读(389) 评论(0) 推荐(0) 编辑
摘要:前言 JDK 1.5 的 java.util.concurrent.locks 包中都是锁,其中有一个抽象类 AbstractQueuedSynchronizer (抽象队列同步器),也就是 AQS, 我们今天就来看看该类。 1.结构 我们看看该类的结构,该类被 CountDown,ThreadPo 阅读全文
posted @ 2018-05-19 23:07 莫那-鲁道 阅读(441) 评论(0) 推荐(0) 编辑
摘要:前言 是一个普通用户不怎么常用的队列,通常在创建无界线程池( )的时候使用,也就是那个非常危险的线程池 。 它是一个非常特殊的阻塞队列,他的模式是:在 的时候,如果没有另一个线程在 take 或者 的话,就会失败,反之,如果在 或者 的时候,没有线程在 ,则也会失败,而这种特性,则非常适合用来做高响 阅读全文
posted @ 2018-05-19 23:07 莫那-鲁道 阅读(298) 评论(0) 推荐(0) 编辑
摘要:前言 在并发编程中,需要处理两个问题:线程之间如何通信及线程之间如何同步。通知是指线程之间以何种机制来交换信息。在命令式编程中, 线程之间的通信机制有两种:共享内存和消息传递 。 在共享内存的并发模型里,线程之间共享程序的公共状态,通过写 读内存中的公共状态进行隐式通信。而子啊消息传递的并发模型里, 阅读全文
posted @ 2018-05-19 23:06 莫那-鲁道 阅读(228) 评论(0) 推荐(0) 编辑
摘要:前言 “分而治之” 一直是一个有效的处理大量数据的方法。著名的 MapReduce 也是采取了分而治之的思想。简单来说,就是如果你要处理1000个数据,但是你并不具备处理1000个数据的能力,那么你可以只处理其中的10个,然后,分阶段处理100次,将100次的结果进行合成,那就是最终想要的对原始的1 阅读全文
posted @ 2018-05-19 23:05 莫那-鲁道 阅读(5737) 评论(0) 推荐(0) 编辑
摘要:前言 今天我们继续分析 java 并发包的源码,今天的主角是谁呢?ConcurrentLinkedQueue,上次我们分析了并发下 ArrayList 的替代 CopyOnWriteArrayList,这次分析则是并发下 LinkedArrayList 的替代 ConcurrentLinkedQue 阅读全文
posted @ 2018-05-19 23:04 莫那-鲁道 阅读(902) 评论(5) 推荐(0) 编辑
摘要:前言 JDK 1.5 之后,Doug Lea 大神为我们写了很多的工具,整个 concurrent 包基本都是他写的。也为我们程序员写好了很多工具,包括我们之前说的线程池,重入锁,线程协作工具,ConcurrentHashMap 等等,今天我们要讲的是和 ConcurrentHashMap 类似的数 阅读全文
posted @ 2018-05-19 23:03 莫那-鲁道 阅读(216) 评论(0) 推荐(0) 编辑
摘要:前言 ArrayList 是一个不安全的容器,在多线程调用 add 方法的时候会出现 ArrayIndexOutOfBoundsException 异常,而 Vector 虽然安全,但由于其 add 方法和 get 方法都使用了 synchronized 关键字,导致在并发时的性能令人担忧,因此,伟 阅读全文
posted @ 2018-05-19 23:03 莫那-鲁道 阅读(162) 评论(0) 推荐(0) 编辑
摘要:前言 首先看看 JDK 文档的描述: 该类提供了线程局部 (thread local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private stat 阅读全文
posted @ 2018-05-19 23:02 莫那-鲁道 阅读(297) 评论(0) 推荐(0) 编辑
摘要:前言 在并发编程中,锁是消耗性能的操作,同一时间只能有一个线程进入同步块修改变量的值,比如下面的代码 如果不加 synchronized 的话,多线程修改 a 的值就会导致结果不正确,出现线程安全问题。但锁又是要给耗费性能的操作。不论是拿锁,解锁,还是等待锁,阻塞,都是非常耗费性能的。那么能不能不加 阅读全文
posted @ 2018-05-19 23:01 莫那-鲁道 阅读(7520) 评论(2) 推荐(0) 编辑
摘要:前言 我们之前分析了Hash的源码,主要是 put 方法。同时,我们知道,HashMap 在并发的时候是不安全的,为什么呢?因为当多个线程对 Map 进行扩容会导致链表成环。不单单是这个问题,当多个线程相同一个槽中插入数据,也是不安全的。而在这之后,我们学习了并发编程,而并发编程中有一个重要的东西, 阅读全文
posted @ 2018-05-19 23:00 莫那-鲁道 阅读(520) 评论(0) 推荐(0) 编辑
摘要:前言 在 JDK 1.6 之前,synchronized 性能令人担忧,但是 1.6 之后,JVM 团队针对 synchronized 做了很多的优化,让 synchroized 在性能层面相比较 ReentrantLock 不相上下。那么,JVM 团队做了哪些优化呢? 首先说,怎么才能优化?我们知 阅读全文
posted @ 2018-05-19 23:00 莫那-鲁道 阅读(212) 评论(0) 推荐(0) 编辑
摘要:前言 在上一篇文章中我们介绍了线程池的使用,那么现在我们有个疑问:线程池到底是怎么实现的?毕竟好奇是人类的天性。那我们今天就来看看吧,扒开 他的源码,一探究竟。 1. 从 Demo 入手 上图是个最简单的demo,我们从这个 demo 开始看源码,首先一步一步来看。 首先我们手动创建了线程池,使用了 阅读全文
posted @ 2018-05-19 21:17 莫那-鲁道 阅读(322) 评论(0) 推荐(0) 编辑
摘要:前言 多线程的软件设计方法确实可以最大限度的发挥现代多核处理器的计算能力,提高生产系统的吞吐量和性能。但是,如果一个系统同时创建大量线程,线程间频繁的切换上下文导致的系统开销将会拖慢整个系统。严重的甚至导致内存耗尽导致OOM异常。因此,在实际的生产环境中,线程的数量必须得到控制,盲目的创建大量新车对 阅读全文
posted @ 2018-05-19 21:12 莫那-鲁道 阅读(470) 评论(0) 推荐(1) 编辑
摘要:前言 在前面的文章中,我们介绍了并发工具中的4个,Samephore,CyclicBarrier,CountDownLatch,Exchanger,但是我们漏了一个,非常的好用的工具,楼主在这里必须加上。 LockSupport LockSupport 是一个非常方便实用的线程 阻塞 工具,他可以在 阅读全文
posted @ 2018-05-19 21:07 莫那-鲁道 阅读(240) 评论(0) 推荐(0) 编辑
摘要:前言 在并发编程的时候,Doug Lea 大师为我们准备了很多的工具,都在 JDK 1.5 版本后的java.util.concurrent 包下,今天楼主就和大家分享一些常用的线程协作的工具。 1. Semaphore 信号量 2. CountDownLatch 倒计时器 3. CyclicBar 阅读全文
posted @ 2018-05-19 21:02 莫那-鲁道 阅读(244) 评论(0) 推荐(1) 编辑
摘要:前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中。在一次学习中去理解这些东西。才能更好的理解 Java 内存模型和 volatile 关键字还有 HB 原则。 楼主今天就尝试着在一篇文章中讲述这三个问 阅读全文
posted @ 2018-05-19 21:01 莫那-鲁道 阅读(337) 评论(0) 推荐(0) 编辑
摘要:前言 今天我们继续学习并发。在之前我们学习了 JMM 的知识,知道了在并发编程中,为了保证线程的安全性,需要保证线程的原子性,可见性,有序性。其中,synchronized 高频出现,因为他既保证了原子性,也保证了可见性和有序性。为什么,因为 synchronized 是锁。通过锁,可以让原本并行的 阅读全文
posted @ 2018-05-19 21:01 莫那-鲁道 阅读(461) 评论(0) 推荐(1) 编辑
摘要:前言 在 Java 刚诞生时,Thread 类就已经有了很多方法,但这些方法由于一些原因(有一些明显的bug或者设计不合理)有些已经废弃了,但是他们的方法名却是非常的好,真的是浪费。我们在进行并发必编程的时候一定要注意这些。 1. 过期方法1 stop 方法 2. 过期方法2 suspend 方法和 阅读全文
posted @ 2018-05-19 21:00 莫那-鲁道 阅读(418) 评论(0) 推荐(1) 编辑
摘要:前言 2018 元旦快乐。 摘要: 1. notify wait 如何使用? 2. 为什么必须在同步块中? 3. 使用 notify wait 实现一个简单的生产者消费者模型 4. 底层实现原理 1. notify wait 如何使用? 今天我们要学习或者说分析的是 Object 类中的 wait 阅读全文
posted @ 2018-05-19 20:52 莫那-鲁道 阅读(3868) 评论(0) 推荐(0) 编辑
摘要:前言 在 Java 的并发编程中,有一个问题需要特别注意,那就是死锁,如果发生了死锁,基本就是重启,而重启将会丢失运行中的数据。所以,了解死锁的形成并排查死锁到预防死锁成了一个重要的问题。 我们了解任何一个事情的步骤是:what,how,why,why not。 1. 什么是死锁? 我们还是直接写一 阅读全文
posted @ 2018-05-19 20:50 莫那-鲁道 阅读(451) 评论(0) 推荐(0) 编辑
摘要:前言 SOFARPC 提供了多种调用方式满足不同的场景。 例如,同步阻塞调用;异步 future 调用,Callback 回调调用,Oneway 调用。 每种调用模式都有对应的场景。类似于单进程中的调用模式。在单进程中,我们可以使用 JDK 的 Future 实现异步,可以通过观察者实现回调。 那么 阅读全文
posted @ 2018-05-09 21:41 莫那-鲁道 阅读(932) 评论(0) 推荐(0) 编辑
摘要:前言 通常 RPC 调用需要客户端使用服务端提供的接口,而具体的形式则是使用 jar 包,通过引用 jar 包获取接口的的具体信息,例如接口名称,方法名称,参数类型,返回值类型。 但也存在一些情况,例如客户端没有 jar 包,或者是跨语言的调用,这个时候,就需要客户端使用字符串进行泛化调用。 如何使 阅读全文
posted @ 2018-05-08 12:58 莫那-鲁道 阅读(1320) 评论(0) 推荐(0) 编辑
摘要:前言 RPC 框架需要维护客户端和服务端的连接,通常是一个客户端对应多个服务端,而客户端看到的是接口,并不是服务端的地址,服务端地址对于客户端来讲是透明的。 那么,如何实现这样一个 RPC 框架的网络连接呢? 我们从 SOFA 中寻找答案。 连接管理器介绍 先从一个小 demo 开始看: 上面的代码 阅读全文
posted @ 2018-05-08 02:03 莫那-鲁道 阅读(403) 评论(0) 推荐(0) 编辑
摘要:前言 SOFA RPC 中对服务地址的选择也抽象为了一条处理链,由每一个 Router 进行处理。同 Filter 一样, SOFA RPC 对 Router 提供了同样的扩展能力。 那么就看看 SOFA 是如何处理的。 如何使用 官方教程如下: 新建扩展文件 META INF/services/s 阅读全文
posted @ 2018-05-08 02:01 莫那-鲁道 阅读(562) 评论(0) 推荐(0) 编辑
摘要:前言 集群中通常一个服务有多个服务提供者。其中部分服务提供者可能由于网络,配置,长时间 fullgc ,线程池满,硬件故障等导致长连接还存活但是程序已经无法正常响应。单机故障剔除功能会将这部分异常的服务提供者进行降级,使得客户端的请求更多地指向健康节点。当异常节点的表现正常后,单机故障剔除功能会对该 阅读全文
posted @ 2018-05-07 00:54 莫那-鲁道 阅读(554) 评论(0) 推荐(0) 编辑
摘要:前言 SOFA 内置负载均衡,支持 5 种负载均衡算法,随机(默认算法),本地优先,轮询算法,一致性 hash,按权重负载轮询(不推荐,已被标注废弃)。 一起看看他们的实现(重点还是一致性 hash)。 源码分析 具体源码在 AbstractLoadBalancer 类中,子类需要实现 doSele 阅读全文
posted @ 2018-05-04 00:43 莫那-鲁道 阅读(490) 评论(0) 推荐(0) 编辑
摘要:前言 SOFA RPC 支持根据权重对服务进行预热功能,具体地址: "预热权重" . 引用官方文档: 预热权重功能让客户端机器能够根据服务端的相应权重进行流量的分发。该功能也常被用于集群内少数机器的启动场景。利用流量权重功能在短时间内对服务端机器进行预热,然后再接收正常的流量比重。 运行机制如下: 阅读全文
posted @ 2018-05-04 00:42 莫那-鲁道 阅读(399) 评论(0) 推荐(0) 编辑
摘要:前言 大部分框架都是事件订阅功能,即观察者模式,或者叫事件机制。通过订阅某个事件,当触发事件时,回调某个方法。该功能非常的好用,而 SOFA 内部也设计了这个功能,并且内部大量使用了该功能。来看看是如何设计的。 源码分析 核心类有 3 个: EventBus 事件总线 Event 事件,即被观察者 阅读全文
posted @ 2018-05-04 00:41 莫那-鲁道 阅读(396) 评论(0) 推荐(0) 编辑
摘要:前言 在 SOFA RPC 的官方介绍里,介绍了自定义线程池,可以为指定服务设置一个独立的业务线程池,和 SOFARPC 自身的业务线程池是隔离的。多个服务可以共用一个独立的线程池。 API使用方式如下: 如上为 HelloService 服务设置了一个自定义线程池。 在 SOFABoot 中如下使 阅读全文
posted @ 2018-05-03 02:38 莫那-鲁道 阅读(1153) 评论(0) 推荐(0) 编辑
摘要:前言 SOFA—RPC 支持数据链路透传功能,官方解释: 链路数据透传功能支持应用向调用上下文中存放数据,达到整个链路上的应用都可以操作该数据。 使用方式如下,可分别向链路的 request 和 response 中放入数据进行透传,并可获取到链路中相应的数据。 使用方式: 源码分析 从这个 4 句 阅读全文
posted @ 2018-05-03 02:38 莫那-鲁道 阅读(546) 评论(1) 推荐(0) 编辑
摘要:前言 我们在之前的文章中已经稍微了解过 SOFA 的扩展机制,我们也说过,一个好的框架,必然是易于扩展的。那么 SOFA 具体是怎么实现的呢? 一起来看看。 如何使用? 看官方的 demo: 1.定义扩展点。 2.定义扩展实现 3.编写扩展描述文件:META INF/services/sofa rp 阅读全文
posted @ 2018-05-03 02:37 莫那-鲁道 阅读(487) 评论(0) 推荐(0) 编辑
摘要:前言 SOFA Boot 现阶段支持 XML 的方式在 Spring 中定义 Bean,通过这些标签,我们就能从 Spring 容器中取出 RPC 中的引用,并进行调用,那么他是如何处理这些自定义标签的呢?一起来看看。 如何使用? 官方例子: 显眼的 sofa 标签。那么如何知道他是怎么处理这些标签 阅读全文
posted @ 2018-05-01 17:53 莫那-鲁道 阅读(2893) 评论(0) 推荐(1) 编辑

点击右上角即可分享
微信分享提示