摘要: 性能与伸缩性使用线程的一种说法是为了提高性能。多线程可以使程序充分利用闲置的资源,提高资源的利用率,同时能够并行处理任务,提高系统的响应性。 但是很显然,引入线程的同时也引入了系统的复杂性。另外系统的性能并不是总是随着线程数的增加而总是提高。性能与伸缩性性能的提升通常意味着可以用更少的资源做更多的事... 阅读全文
posted @ 2014-12-02 22:47 小光zfg 阅读(387) 评论(0) 推荐(0)
摘要: 常见的并发陷阱volatilevolatile只能强调数据的可见性,并不能保证原子操作和线程安全,因此volatile不是万能的。参考指令重排序volatile最常见于下面两种场景。a. 循环检测机制volatilebooleandone=false;while(!done){dosomething... 阅读全文
posted @ 2014-12-02 22:46 小光zfg 阅读(369) 评论(0) 推荐(0)
摘要: 常见的并发场景线程池并发最常见用于线程池,显然使用线程池可以有效的提高吞吐量。最常见、比较复杂一个场景是Web容器的线程池。Web容器使用线程池同步或者异步处理HTTP请求,同时这也可以有效的复用HTTP连接,降低资源申请的开销。通常我们认为HTTP请求时非常昂贵的,并且也是比较耗费资源和性能的,所... 阅读全文
posted @ 2014-12-02 22:44 小光zfg 阅读(221) 评论(0) 推荐(0)
摘要: 死锁与活跃度前面谈了很多并发的特性和工具,但是大部分都是和锁有关的。我们使用锁来保证线程安全,但是这也会引起一些问题。锁顺序死锁(lock-ordering deadlock):多个线程试图通过不同的顺序获得多个相同的资源,则发生的循环锁依赖现象。动态的锁顺序死锁(Dynamic Lock Orde... 阅读全文
posted @ 2014-12-02 22:40 小光zfg 阅读(295) 评论(0) 推荐(0)
摘要: 并发包引入的工具类很多方法都会抛出一定的异常,这些异常描述了任务在线程池中执行时发生的例外情况,而通常这些例外需要应用程序进行捕捉和处理。例如在Future接口中有如下一个API:java.util.concurrent.Future.get(long,TimeUnit)throwsInterrup... 阅读全文
posted @ 2014-12-02 22:39 小光zfg 阅读(298) 评论(0) 推荐(0)
摘要: 线程池任务执行结果这一节来探讨下线程池中任务执行的结果以及如何阻塞线程、取消任务等等。1packageinfo.imxylz.study.concurrency.future;23publicclassSleepForResultDemoimplementsRunnable {45staticboo... 阅读全文
posted @ 2014-12-02 22:38 小光zfg 阅读(303) 评论(0) 推荐(0)
摘要: 线程池任务执行流程我们从一个API开始接触Executor是如何处理任务队列的。java.util.concurrent.Executor.execute(Runnable)Executes the given task sometime in the future. The task may ex... 阅读全文
posted @ 2014-12-02 22:37 小光zfg 阅读(296) 评论(0) 推荐(0)
摘要: 线程池数据结构与线程构造方法由于已经看到了ThreadPoolExecutor的源码,因此很容易就看到了ThreadPoolExecutor线程池的数据结构。图1描述了这种数据结构。图1 ThreadPoolExecutor 数据结构其实,即使没有上述图形描述ThreadPoolExecutor的数... 阅读全文
posted @ 2014-12-02 22:36 小光zfg 阅读(228) 评论(0) 推荐(0)
摘要: 我们知道线程是有多种执行状态的,同样管理线程的线程池也有多种状态。JVM会在所有线程(非后台daemon线程)全部终止后才退出,为了节省资源和有效释放资源关闭一个线程池就显得很重要。有时候无法正确的关闭线程池,将会阻止JVM的结束。线程池Executor是异步的执行任务,因此任何时刻不能够直接获取提... 阅读全文
posted @ 2014-12-02 22:35 小光zfg 阅读(285) 评论(0) 推荐(0)
摘要: Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。下面这张图完整描述了线程池的类体系结构。首先Executor的execute方法只是执行一个Runnable的任务,当然了从某... 阅读全文
posted @ 2014-12-02 22:33 小光zfg 阅读(218) 评论(0) 推荐(0)
摘要: 从这一节开始正式进入线程池的部分。其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充、完善。其实线程池是并发包里面很重要的一部分,在实际情况中也是使用很多的一个重要组件。下图描述的是线程池API的一部分。广义上的完整线程池可能还包括Threa... 阅读全文
posted @ 2014-12-02 22:30 小光zfg 阅读(223) 评论(0) 推荐(0)
摘要: 本小节是《并发容器》的最后一部分,这一个小节描述的是针对List/Set接口的一个线程版本。在《并发队列与Queue简介》中介绍了并发容器的一个概括,主要描述的是Queue的实现。其中特别提到一点LinkedList是List/Queue的实现,但是LinkedList确实非线程安全的。不管Bloc... 阅读全文
posted @ 2014-12-02 22:27 小光zfg 阅读(853) 评论(0) 推荐(0)
摘要: 可以在对中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给exchange方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象。Exchanger 可能被视为SynchronousQueue的双向形式。换句话说Exchanger提供的是一个交换服务,允许原子性的交换两个(多个)... 阅读全文
posted @ 2014-12-02 22:26 小光zfg 阅读(234) 评论(0) 推荐(0)
摘要: 这个小节介绍Queue的最后一个工具,也是最强大的一个工具。从名称上就可以看到此工具的特点:双向并发阻塞队列。所谓双向是指可以从队列的头和尾同时操作,并发只是线程安全的实现,阻塞允许在入队出队不满足条件时挂起线程,这里说的队列是指支持FIFO/FILO实现的链表。首先看下LinkedBlocking... 阅读全文
posted @ 2014-12-02 22:25 小光zfg 阅读(199) 评论(0) 推荐(0)
摘要: 有一段时间没有更新了。接着上节继续吧。Queue除了前面介绍的实现外,还有一种双向的Queue实现Deque。这种队列允许在队列头和尾部进行入队出队操作,因此在功能上比Queue显然要更复杂。下图描述的是Deque的完整体系图。需要说明的是LinkedList也已经加入了Deque的一部分(Link... 阅读全文
posted @ 2014-12-02 22:24 小光zfg 阅读(370) 评论(0) 推荐(0)
摘要: 在Set中有一个排序的集合SortedSet,用来保存按照自然顺序排列的对象。Queue中同样引入了一个支持排序的FIFO模型。并发队列与Queue简介中介绍了,PriorityQueue和PriorityBlockingQueue就是支持排序的Queue。显然一个支持阻塞的排序Queue要比一个非... 阅读全文
posted @ 2014-12-02 22:22 小光zfg 阅读(222) 评论(0) 推荐(0)
摘要: 在上一节中详细分析了LinkedBlockingQueue的实现原理。实现一个可扩展的队列通常有两种方式:一种方式就像LinkedBlockingQueue一样使用链表,也就是每一个元素带有下一个元素的引用,这样的队列原生就是可扩展的;另外一种就是通过数组实现,一旦队列的大小达到数组的容量的时候就将... 阅读全文
posted @ 2014-12-02 22:21 小光zfg 阅读(237) 评论(0) 推荐(0)
摘要: 在《并发容器 part 4 并发队列与Queue简介》节中的类图中可以看到,对于Queue来说,BlockingQueue是主要的线程安全版本。这是一个可阻塞的版本,也就是允许添加/删除元素被阻塞,直到成功为止。BlockingQueue相对于Queue而言增加了两个操作:put/take。下面是一... 阅读全文
posted @ 2014-12-02 22:20 小光zfg 阅读(179) 评论(0) 推荐(0)
摘要: ConcurrentLinkedQueue是Queue的一个线程安全实现。先来看一段文档说明。一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列获取操作从队列头... 阅读全文
posted @ 2014-12-02 22:19 小光zfg 阅读(315) 评论(0) 推荐(0)
摘要: Queue是JDK 5以后引入的新的集合类,它属于Java Collections Framework的成员,在Collection集合中和List/Set是同一级别的接口。通常来讲Queue描述的是一种FIFO的队列,当然不全都是,比如PriorityQueue是按照优先级的顺序(或者说是自然顺序... 阅读全文
posted @ 2014-12-02 22:18 小光zfg 阅读(272) 评论(0) 推荐(0)
摘要: 在上一篇中介绍了HashMap的原理,这一节是ConcurrentMap的最后一节,所以会完整的介绍ConcurrentHashMap的实现。ConcurrentHashMap原理在读写锁章节部分介绍过一种是用读写锁实现Map的方法。此种方法看起来可以实现Map响应的功能,而且吞吐量也应该不错。但是... 阅读全文
posted @ 2014-12-02 22:17 小光zfg 阅读(186) 评论(0) 推荐(0)
摘要: 本来想比较全面和深入的谈谈ConcurrentHashMap的,发现网上有很多对HashMap和ConcurrentHashMap分析的文章,因此本小节尽可能的分析其中的细节,少一点理论的东西,多谈谈内部设计的原理和思想。要谈ConcurrentHashMap的构造,就不得不谈HashMap的构造,... 阅读全文
posted @ 2014-12-02 22:16 小光zfg 阅读(225) 评论(0) 推荐(0)
摘要: 从这一节开始正式进入并发容器的部分,来看看JDK 6带来了哪些并发容器。在JDK 1.4以下只有Vector和Hashtable是线程安全的集合(也称并发容器,Collections.synchronized*系列也可以看作是线程安全的实现)。从JDK 5开始增加了线程安全的Map接口Concurr... 阅读全文
posted @ 2014-12-02 22:15 小光zfg 阅读(192) 评论(0) 推荐(0)
摘要: 主要谈谈锁的性能以及其它一些理论知识,内容主要的出处是《Java Concurrency in Practice》,结合自己的理解和实际应用对锁机制进行一个小小的总结。首先需要强调的一点是:所有锁(包括内置锁和高级锁)都是有性能消耗的,也就是说在高并发的情况下,由于锁机制带来的上下文切换、资源同步等... 阅读全文
posted @ 2014-12-02 22:11 小光zfg 阅读(142) 评论(0) 推荐(0)
摘要: 这一节主要是谈谈读写锁的实现。上一节中提到,ReadWriteLock看起来有两个锁:readLock/writeLock。如果真的是两个锁的话,它们之间又是如何相互影响的呢?事实上在ReentrantReadWriteLock里锁的实现是靠java.util.concurrent.locks.Re... 阅读全文
posted @ 2014-12-02 22:10 小光zfg 阅读(235) 评论(0) 推荐(0)
摘要: 从这一节开始介绍锁里面的最后一个工具:读写锁(ReadWriteLock)。ReentrantLock 实现了标准的互斥操作,也就是一次只能有一个线程持有锁,也即所谓独占锁的概念。前面的章节中一直在强调这个特点。显然这个特点在一定程度上面减低了吞吐量,实际上独占锁是一种保守的锁策略,在这种情况下任何... 阅读全文
posted @ 2014-12-02 22:09 小光zfg 阅读(141) 评论(0) 推荐(0)
摘要: Semaphore 是一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire(),然后再获取该许可。每个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore只对可用许可的号码进行计数,并采取相应... 阅读全文
posted @ 2014-12-02 22:02 小光zfg 阅读(185) 评论(0) 推荐(0)
摘要: 如果说CountDownLatch是一次性的,那么CyclicBarrier正好可以循环使用。它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。所谓屏障点就是一组任务执行完毕的时刻。清单1 一个使用CyclicBarrier的例子package xylz.... 阅读全文
posted @ 2014-12-02 22:00 小光zfg 阅读(146) 评论(0) 推荐(0)
摘要: 此小节介绍几个与锁有关的有用工具。闭锁(Latch)闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态。通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻断,一旦大门打开所有线程都将通过,但是一旦大门打开,所有线程都通过了,那么这个闭锁的状态就失效了,门的状... 阅读全文
posted @ 2014-12-02 21:58 小光zfg 阅读(177) 评论(0) 推荐(0)
摘要: 本小节介绍锁释放Lock.unlock()。Release/TryReleaseunlock操作实际上就调用了AQS的release操作,释放持有的锁。public final boolean release(int arg) { if (tryRelease(arg)) { Node h = he... 阅读全文
posted @ 2014-12-02 21:57 小光zfg 阅读(180) 评论(0) 推荐(0)
摘要: 接上篇,这篇从Lock.lock/unlock开始。特别说明在没有特殊情况下所有程序、API、文档都是基于JDK 6.0的。public void java.util.concurrent.locks.ReentrantLock.lock()获取锁。如果该锁没有被另一个线程保持,则获取该锁并立即返回... 阅读全文
posted @ 2014-12-02 21:56 小光zfg 阅读(162) 评论(0) 推荐(0)
摘要: 在理解J.U.C原理以及锁机制之前,我们来介绍J.U.C框架最核心也是最复杂的一个基础类:java.util.concurrent.locks.AbstractQueuedSynchronizer。AQSAbstractQueuedSynchronizer,简称AQS,是J.U.C最复杂的一个类,导... 阅读全文
posted @ 2014-12-02 21:53 小光zfg 阅读(191) 评论(0) 推荐(0)
摘要: 前面的章节主要谈谈原子操作,至于与原子操作一些相关的问题或者说陷阱就放到最后的总结篇来整体说明。从这一章开始花少量的篇幅谈谈锁机制。上一个章节中谈到了锁机制,并且针对于原子操作谈了一些相关的概念和设计思想。接下来的文章中,尽可能的深入研究锁机制,并且理解里面的原理和实际应用场合。尽管synchron... 阅读全文
posted @ 2014-12-02 21:52 小光zfg 阅读(151) 评论(0) 推荐(0)
摘要: 在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁)。锁机制存在以下问题:(1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。(2)一个线程持有锁会导致其它所有需要此锁的线程挂起。(3)如果一个优先级高的线程等... 阅读全文
posted @ 2014-12-02 21:48 小光zfg 阅读(135) 评论(0) 推荐(0)
摘要: 在这个小结里面重点讨论原子操作的原理和设计思想。由于在下一个章节中会谈到锁机制,因此此小节中会适当引入锁的概念。在Java Concurrency in Practice中是这样定义线程安全的:当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用方... 阅读全文
posted @ 2014-12-02 21:47 小光zfg 阅读(170) 评论(0) 推荐(0)
摘要: 在这一部分开始讨论数组原子操作和一些其他的原子操作。AtomicIntegerArray/AtomicLongArray/AtomicReferenceArray的API类似,选择有代表性的AtomicIntegerArray来描述这些问题。int get(int i)获取位置i的当前值。很显然,由... 阅读全文
posted @ 2014-12-02 21:46 小光zfg 阅读(255) 评论(0) 推荐(0)
摘要: 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始)。很多情况下我们只是需要一个简单的、高效的、线程安全的递增递减方案。注意,这里有三个条件:简单,意味着程序员尽可能少的操作底层或者实现... 阅读全文
posted @ 2014-12-02 21:45 小光zfg 阅读(146) 评论(0) 推荐(0)
摘要: 去年年底有一个Guice的研究计划,可惜由于工作“繁忙”加上实际工作中没有用上导致“无疾而终”,最终只是完成了Guice的初步学习教程,深入的研究没有继续进行下去。最近一直用的比较多的就是java.util.concurrent(J.U.C),实际上这块一直也没有完全深入研究,这次准备花点时间研究下... 阅读全文
posted @ 2014-12-02 21:43 小光zfg 阅读(140) 评论(0) 推荐(0)
摘要: 这是一份完整的Java 并发整理笔记,记录了我最近几年学习Java并发的一些心得和体会。J.U.C 整体认识原子操作 part 1 从AtomicInteger开始原子操作 part 2 数组、引用的原子操作原子操作 part 3 指令重排序与happens-before法则原子操作 part 4 ... 阅读全文
posted @ 2014-12-02 21:40 小光zfg 阅读(208) 评论(0) 推荐(0)
摘要: 搭建Spring、Spring MVC、Mybatis和Freemarker1、pom文件 4.0.0 com.candle home-finance-sample war 0.0.1-SNAPSHOT home-finance-sample Maven Weba... 阅读全文
posted @ 2014-12-02 21:28 小光zfg 阅读(174) 评论(0) 推荐(0)
摘要: 第1章 概述 1.1 阅读顺序 1.2 本书纵览 1.3 导引 1.4 读者对象 1.5 进一步的资源 1.6 升级到spring的新版本 1.7 本章小结 第2章 spring框架 2.1 控制反转 2.1.1 控制反转实例 2.1.2 小结 2.2 依赖注入 2.2... 阅读全文
posted @ 2014-12-02 21:18 小光zfg 阅读(200) 评论(0) 推荐(0)