BlockingQueue与Condition原理解析

 我在前段时间写了一篇关于AQS的文章,在文章里边我说几乎所有在JUC包中的所有多线程相关的类都和AQS相关,今天我就在这里总结一下另一个依赖于AQS来实现的同步工具类:BlockingQueue。我们主要以ArrayBlockingQueue为主来分析相关的源码。

阻塞队列

 相信大多数同学都是在学习线程池相关知识时了解到阻塞队列的概念的。知道各种类型的阻塞队列对线程池初始化时的影响。在java doc中这样定义阻塞队列。当从阻塞队列获取元素但是队列为空时,当前线程会阻塞直到另一个线程向阻塞队列中添加一个元素;类似的,当向一个阻塞队列加入元素时,如果队列已经满了,当前线程也会阻塞知道另外一个线程从队列中读取一个元素。阻塞队列一般都是FIFO,用来实现生产者和消费者模式。阻塞队列的方法通过四种不同的方式来处理操作无法被立即完成的情况,这四种情况分别为抛出异常,返回特殊值(null或在是false),阻塞当前线程直到执行结束,最后一种是只阻塞固定时间,然后还未执行成功就放弃操作。这些方法都总结在下边这种表中了。

BlockingQueue

 我们就只分析puttake方法。

put和take函数

 我们都知道,使用同步队列可以很轻松的实现生产者-消费者模式,其实,同步队列就是按照生产者-消费者的模式来实现的,我们可以将put函数看作生产者的操作,take是消费者的操作。
put函数会在队列末尾添加元素,如果队列已经满了,无法添加元素的话,就一直阻塞等待到可以加入为止。函数的源码如下所示。

Read More
Share

LongAdder解析

 对LongAdder的最初了解是从Coolshell上的一篇文章中获得的,但是一直都没有深入的了解过其实现,只知道它相较于AtomicLong来说,更加适合读多写少的并发情景。今天,我们就研究一下LongAdder的原理,探究一下它如此高效的原因。

基本原理和思想

 我们都知道AtomicLong是通过无限循环不停的采取CAS的方法去设置value,直到成功为止。那么当并发数比较多或出现更新热点时,就会导致CAS的失败机率变高,重试次数更多,越多的线程重试,CAS失败的机率越高,形成恶性循环,从而降低了效率。而LongAdder的原理就是降低对value更新的并发数,也就是将对单一value的变更压力分散到多个value值上,降低单个value的“热度”
 我们知道LongAdder的大致原理之后,再来详细的了解一下它的具体实现,其中也有很多值得借鉴的并发编程的技巧。

Add操作

public void add(long x) {

Read More
Share

分布式一致性算法Paxos

 最近在学习zookeeper原理的时候了解到了paxos算法,看了几篇文章之后还是感觉有些迷糊,后来看了知行学社的paxos视频才对这个算法有了一定的了解,这里就做一下总结.

Paxos简介

 Paxos是Lamport于1990年提出的一种基于消息传递而具有高度容错特性的分布式一致性算法.这个算法是分布式中最为重要的算法,Google Chubby的作者Mike Burrows说过这个世界上只有一种一致性算法,那就是Paxos,其他算法都是残次品.具体Paxos算法的详细内涵和故事背景大家可以参考知乎上的回答;

Paxos的使用场景和假设

 我们都知道基于消息传递通信模型的分布式系列,不可避免的会发生以下错误:进程可能会慢,被杀死或在重启,消息可能会有延迟,丢失和重复.Paxos算法解决的问题就是在一个可能发生上述异常的分布式系统中如何就某个值达成一致,保证无论发生以上任何异常,都不会破坏决议的一致性。但是Paxos算法也有一定的使用假设。一个假设是在消息传递的过程中不会出现拜占庭将军问题:即虽然有可能一个消息被传递两次,但是绝对不会出现错误的消息。另一个假设是提议不会被反对,只能被同意或在被更新的提议替换。
 Paxos协议中有三种角色,每个节点可以扮演多个角色:

  • 倡议者(Proposer):提议者可以提出提议(数值或在操作命令)以供投票表决。
Read More
Share

AbstractQueuedSynchronizer超详细原理解析

 今天我们来研究学习一下AbstractQueuedSynchronizer类的相关原理,java.util.concurrent包中很多类都依赖于这个类所提供的队列式的同步器,比如说常用的ReentranLock,SemaphoreCountDownLatch等.
 为了方便理解,我们以一段使用ReentranLock的代码为例,讲解ReentranLock每个方法中有关AQS的使用.

ReentranLock示例

 我们都知道ReentranLock的加锁行为和Synchronized类似,都是可重入的锁,但是二者的实现方式确实完全不同的,我们之后也会讲解Synchronized的原理.除此之外,Synchronized的阻塞无法被中断,而ReentrantLock则提供了可中断的阻塞下面的代码是ReentranLock的相关API,我们就以此为顺序,依次讲解.

ReentrantLock lock = new ReentrantLock();
lock.lock();

Read More
Share

Netty源码(三):I/O模型和Java NIO底层原理

上一篇文章我们主要讲解了Netty的ChannelPipeline,了解到不同的Channel可以提供基于不同网络协议的通信处理.既然涉及到网络通信,就不得不说一下多线程,同步异步相关的知识了.Netty的网络模型是多线程的Reactor模式,所有I/O请求都是异步调用,我们今天就来探讨一下一些基础概念和Java NIO的底层机制.
 为了节约你的时间,本文主要内容如下:

  • 异步,阻塞的概念
  • 操作系统I/O的类型
  • Java NIO的Linux底层实现
Read More
Share

Netty源码(二):Netty的Channel和Pipeline

 本文主要讲述Netty框架中Channel相关的知识,Netty通过Channel和Pipeline等一些组件提供了所谓的Universal Communication API.与Channel相关的知识点比较多,本篇文章就主要讲解一下ChannelPipeline的事件处理流原理.Channel,EventLoopChannelFuture的相关知识下篇文章中再进行讲述.

官方文档上的Channel

 官方文档上给出的解释是Channel是与网络Socket相关的或具有一定I/O能力的组件.一个Channel可以给用户提供:

  • 当前Channel的状态(比如,是否保存Open状态,是否处于连接状态)
  • Channel的配置参数,比如说buffer的大小
Read More
Share

Netty源码(一):Netty中的Buffer

 最近我学习了NIO相关的知识,然后发现了Netty这个基于NIO的网络应用框架,于是就研究起Netty框架源码,来好好体会一下网络框架的设计理念和思想.
 这个系列的文章不仅会总结Netty各个模块的源码原理,也会写出一些自己对这些设计的理解和体会.
 我基本按照并发编程网上这个系列文章的顺序来进行系列文章的顺序,不同的是我是基于Netty4.1的源码进行分析和讲解.
 为了节约你的时间,本篇文章主要内容如下:

  • Netty的Buffer的内存模型,涉及读写指针
  • Netty的Buffer框架
  • Netty的Pool原理,轻量对象池
Read More
Share

关于Android MVP模式的思考

 这一周对现有的Android项目进行了框架重构,使用MVP模式来重新构建整个项目和包结构。今天就来总结一下我在这个过程中理解和实践吧。

MVP概述

 MVP是指Model,View和Presenter的缩写,是MVC模式的一种改进版。MVP是一种非常适合Android应用的开发模式,它将把逻辑相关代码从presentation Layer中分离出去,所以,所有界面应该显示什么和界面如何显示这些是相互分离的, 在理想状态下,MVP模式可以随意切换视图显示的形式。
 但是,需要首先声明的是,MVP并不是一个框架模式,它只负责presentation Layer。在Android项目中,还可能存在Domain Layer和Data Layer,它们分别负责业务逻辑和数据存储。关于三个layer的讨论,可以查看clear Architecture

mvp.png

The presenter

 The presenter充当的是view和model模块中间人的角色。它从model模块获得数据并发送给view模块。但是不同于MVC,presenter模块也决定用户和界面交互时界面如何响应

The View

 View模块,一般由Activity或者Fragment实现,每个View实例一般都包含一个presenter实例的引用,并负责实例化presenter。理想情况下,你可以使用dagger来实现依赖注入。view的任务就是当用户操作界面时,调用presenter实例的功能来进行响应。

Read More
Share

《暗时间》摘要一

 我阅读刘未鹏学长的博客文章已经很长时间了,今年过年前买了这本《暗时间》,希望能够充分的理解和学习他思维相关的知识和见解。我在去年也读过了一些书籍,但是都是匆匆阅读,很少有思考和反思;不能光读书,还要进行必要的思考,否则只是海绵型的学习模型,以后要做读书笔记和读后感。

理智和情感

 这一章主要介绍了“一脑还是两脑”的问题。总所众知,我们的大脑分为左右两个半脑,不同的半脑的不同区域我们身体的不同部位。那么我们的思维是否也是如此?当我们进行思考或者做出决策时,这些大脑活动都来自于同一个区域吗?
 作者在本章的开始列举了很多因为大脑特定区域受伤而导致失去自控力和行为能力的例子,来证明我们大脑思维的分区域处理。作者将其分为情绪思维和理性思维。不同的大脑皮层区域负责二者,这些区域形成的时间不同。管理情绪思维的大脑皮层几乎从动物时代就存在了,但是理性思维的大脑皮层则是很晚才进化而来的。所以,理性思维区域要弱于情绪思维区域,这就导致了

只要我们的情绪大脑首先认定了一件事情,我们那点可怜的理性思维便很容易屈从于情绪大脑发下的命令——把事情往利于自己的方向解释

Read More
Share

Android性能优化(一):TraceView

 最近,我准备好好研究一下Android性能优化方面的相关知识,准备从应用流畅度开始,边看《移动App性能评测与优化》边自己实践,希望可以补足一下自己在优化这方面的空白。
 工欲善其事必先利其器,我先学习了TraceView这个大神器的使用方法。下面就来总结一下。
 为了节省你的时间,本文主要内容如下:

  • TraceView两种使用方法
  • TraceView各项数据的含义

Read More
Share