`
文章列表
语言篇——lambda,方法引用,目标类型和默认方法 关于 本文介绍了 Java SE 8 中新引入的 lambda 语言特性以及这些特性背后的设计思想。这些特性包括: lambda 表达式(又被成为“闭包”或“匿名方法”) 方法引用和构造方法引用 扩展的目标类型和类型推导 接口中的默认方法和静态方法 1. 背景 Java 是一门面向对象编程语言。面向对象编程语言和函数式编程语言中的基本元素(Basic Values)都可以动态封装程序行为:面向对象编程语言使用带有方法的对象封装行为,函数式编程语言使用函数封装行为。但这个相同点并不明显,因为Jav ...
Spring 的 JdbcTemplate 为我们操作数据库提供非常大的便利,不需要显式的管理资源和处理异常。在我们进入到了 Java 8 后,JdbcTemplate 方法中的回调函数可以用 Lambda 表达式进行简化,而本文要说的正是这种 Lambda 简化容易给我们带来的一个 Bug, 这是我在一个实际项目中写的单元测试发现的。 下面就是我们的一个样板代码,在我们的 UserRespository 中有一个方法 findAll() 用于获得所有用户:     public List<User> findAll(){ List<User> use ...
一.内存模型的相关概念   大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。   也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算 ...
Java内存模型很好的说明了JVM是如何在内存里工作的,JVM可以理解为java执行的一个操作系统,作为一个操作系统就有内存模型,这就是我们常说的JAVA内存模型。 如果我们想正确的写多线程的并行程序。理解好java内存模型在多 ...
线程池架构图 线程池的架构图如下:     1. Executor 它是"执行者"接口,它是来执行任务的。准确的说,Executor提供了execute()接口来执行已提交的 Runnable 任务的对象。Executor存在的目的是提供一种将"任务提交"与"任务如何运行"分离开来的机制。它只包含一个函数接口:
Java集合包 java集合的架构。主体内容包括Collection集合和Map类;而Collection集合又可以划分为List(队列)和Set(集合)。 1. List的实现类主要有: LinkedList, ArrayList, Vector, Stack。 (01) LinkedList是双向链表实现的双端队列;它不是线程安全的,只适用于单线程。(02) ArrayList是数组实现的队列,它是一个动态数组;它也不是线程安全的,只适用于单线程。(03) Vector是数组实现的矢量队列,它也一个动态数组;不过和ArrayList不同的是,Vector是线程安全的,它支持并发。( ...
Java中的锁,可以分为"同步锁"和"JUC包中的锁"。   同步锁   即通过synchronized关键字来进行同步,实现对竞争资源的互斥访问的锁。Java 1.0版本中就已经支持同步锁了。   同步锁的原理是,对于每一个对象,有且仅有一个同步锁;不同的线程能共同访问该同步锁。但是,在同一个时间点,该同步锁能且只能被一个线程获取到。这样,获取到同步锁的线程就能进行CPU调度,从而在CPU上执行;而没有获取到同步锁的线程,必须进行等待,直到获取到同步锁之后才能继续运行。这就是,多线程通过同步锁进行同步的原理! JUC包中的锁    ...
根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类。 1. 基本类型: AtomicInteger, AtomicLong, AtomicBoolean ;2. 数组类型: AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray ;3. 引用类型: AtomicReference, AtomicStampedRerence, AtomicMarkableReference ;4. 对象的属性修改类型: AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicRef ...
线程状态图        
解决的问题 当我们有多个消息的生产者线程,一个消费者线程时,他们之间如何进行高并发、线程安全的协调? 很简单,用一个队列。   当我们有多个消息的生产者线程,多个消费者线程,并且每一条消息需要被所有的消 ...
Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。基于Disruptor开发的系统单线程能支撑每秒600万订单,2010年在QCon演讲后,获得了业界关注。2011年,企业应用软件专家Martin Fowler专门撰写长文介绍。同年它还获得了Oracle官方的Duke大奖。 目前,包括Apache Storm、Camel、Log4j 2在内的很多知名项目都应用了Disruptor以获取高性能。在美团技术团队它也有不少应用,有的项目架构借鉴了它的设计机制。本文从实战角度剖析了Disrupt ...
操作系统中的管程 如果你在大学学习过操作系统,你可能还记得管程(monitors)在操作系统中是很重要的概念。同样Monitor在java同步机制中也有使用。 管程 (英语:Monitors,也称为监视器) 是一种程序结构,结构内的多个子程 ...
  1.问题 batch.size和linger.ms是对kafka producer性能影响比较大的两个参数。batch.size是producer批量发送的基本单位,默认是16384Bytes,即16kB;lingger.ms是sender线程在检查batch是否ready时候,判断有没有过期的参数,默认大小是0ms。 那么producer是按照batch.size大小批量发送消息呢,还是按照linger.ms的时间间隔批量发送消息呢?这里先说结论:其实满足batch.size和ling.ms之一,producer便开始发送消息。   2.源码分析 首先sender线程主要代 ...
为了避免频繁的内存分配给系统带来负担以及GC对系统性能带来波动,Netty4提出了全新的内存管理,使用了全新的内存池来管理内存的分配和回收。内存池这块的代码复杂难懂,而且几乎没有注释阅读起来比较费力,特别是以前没有接触过内存分配算法的阅读起来更为蛋疼,好在经过几个晚上的努力,终于捋出了一些端倪,特来此记录一番。   Netty4的内存池集大家之精华,参考了各路英雄豪杰的优秀思想,它参考了slab分配,Buddy(伙伴)分配。接触过memcached的应该了解slab分配,它的思路是把内存分割成大小不等的内存块,用户线程请求内存时根据请求的内存大小分配最贴近size的内存块,在减少内存碎片 ...
一、Buddy算法     DMA(Direct Memory Access,直接内存存取)、常规、高端内存这3个区域都采用buddy算法进行管理,把空闲的页以2的n次方为单位进行管理,因此Linux最底层的内存申请都是以2n 为单位的。Buddy算法最主要的的特点任何时候区域里的空闲内存都能以2的n次方进行拆分或合并。 例如,假设ZONE_NORMAL有16页内存(24),此时有人申请一页内存,Buddy算法会把剩下的15页拆分成8+4+2+1,放到不同的链表中去。此时再申请4页,直接给4页,若再申请4页,则从8页中给4页,正好剩下4页。Buddy算法的精髓在于任 ...
Global site tag (gtag.js) - Google Analytics