摘要:
性能与伸缩性使用线程的一种说法是为了提高性能。多线程可以使程序充分利用闲置的资源,提高资源的利用率,同时能够并行处理任务,提高系统的响应性。 但是很显然,引入线程的同时也引入了系统的复杂性。另外系统的性能并不是总是随着线程数的增加而总是提高。性能与伸缩性性能的提升通常意味着可以用更少的资源做更多的事... 阅读全文
摘要:
常见的并发陷阱volatilevolatile只能强调数据的可见性,并不能保证原子操作和线程安全,因此volatile不是万能的。参考指令重排序volatile最常见于下面两种场景。a. 循环检测机制volatilebooleandone=false;while(!done){dosomething... 阅读全文
摘要:
常见的并发场景线程池并发最常见用于线程池,显然使用线程池可以有效的提高吞吐量。最常见、比较复杂一个场景是Web容器的线程池。Web容器使用线程池同步或者异步处理HTTP请求,同时这也可以有效的复用HTTP连接,降低资源申请的开销。通常我们认为HTTP请求时非常昂贵的,并且也是比较耗费资源和性能的,所... 阅读全文
摘要:
死锁与活跃度前面谈了很多并发的特性和工具,但是大部分都是和锁有关的。我们使用锁来保证线程安全,但是这也会引起一些问题。锁顺序死锁(lock-ordering deadlock):多个线程试图通过不同的顺序获得多个相同的资源,则发生的循环锁依赖现象。动态的锁顺序死锁(Dynamic Lock Orde... 阅读全文
摘要:
并发包引入的工具类很多方法都会抛出一定的异常,这些异常描述了任务在线程池中执行时发生的例外情况,而通常这些例外需要应用程序进行捕捉和处理。例如在Future接口中有如下一个API:java.util.concurrent.Future.get(long,TimeUnit)throwsInterrup... 阅读全文
摘要:
线程池任务执行结果这一节来探讨下线程池中任务执行的结果以及如何阻塞线程、取消任务等等。1packageinfo.imxylz.study.concurrency.future;23publicclassSleepForResultDemoimplementsRunnable {45staticboo... 阅读全文
摘要:
线程池任务执行流程我们从一个API开始接触Executor是如何处理任务队列的。java.util.concurrent.Executor.execute(Runnable)Executes the given task sometime in the future. The task may ex... 阅读全文
摘要:
线程池数据结构与线程构造方法由于已经看到了ThreadPoolExecutor的源码,因此很容易就看到了ThreadPoolExecutor线程池的数据结构。图1描述了这种数据结构。图1 ThreadPoolExecutor 数据结构其实,即使没有上述图形描述ThreadPoolExecutor的数... 阅读全文
摘要:
我们知道线程是有多种执行状态的,同样管理线程的线程池也有多种状态。JVM会在所有线程(非后台daemon线程)全部终止后才退出,为了节省资源和有效释放资源关闭一个线程池就显得很重要。有时候无法正确的关闭线程池,将会阻止JVM的结束。线程池Executor是异步的执行任务,因此任何时刻不能够直接获取提... 阅读全文
摘要:
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。下面这张图完整描述了线程池的类体系结构。首先Executor的execute方法只是执行一个Runnable的任务,当然了从某... 阅读全文
摘要:
从这一节开始正式进入线程池的部分。其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充、完善。其实线程池是并发包里面很重要的一部分,在实际情况中也是使用很多的一个重要组件。下图描述的是线程池API的一部分。广义上的完整线程池可能还包括Threa... 阅读全文
摘要:
本小节是《并发容器》的最后一部分,这一个小节描述的是针对List/Set接口的一个线程版本。在《并发队列与Queue简介》中介绍了并发容器的一个概括,主要描述的是Queue的实现。其中特别提到一点LinkedList是List/Queue的实现,但是LinkedList确实非线程安全的。不管Bloc... 阅读全文
摘要:
可以在对中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给exchange方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象。Exchanger 可能被视为SynchronousQueue的双向形式。换句话说Exchanger提供的是一个交换服务,允许原子性的交换两个(多个)... 阅读全文
摘要:
这个小节介绍Queue的最后一个工具,也是最强大的一个工具。从名称上就可以看到此工具的特点:双向并发阻塞队列。所谓双向是指可以从队列的头和尾同时操作,并发只是线程安全的实现,阻塞允许在入队出队不满足条件时挂起线程,这里说的队列是指支持FIFO/FILO实现的链表。首先看下LinkedBlocking... 阅读全文
摘要:
有一段时间没有更新了。接着上节继续吧。Queue除了前面介绍的实现外,还有一种双向的Queue实现Deque。这种队列允许在队列头和尾部进行入队出队操作,因此在功能上比Queue显然要更复杂。下图描述的是Deque的完整体系图。需要说明的是LinkedList也已经加入了Deque的一部分(Link... 阅读全文
摘要:
在Set中有一个排序的集合SortedSet,用来保存按照自然顺序排列的对象。Queue中同样引入了一个支持排序的FIFO模型。并发队列与Queue简介中介绍了,PriorityQueue和PriorityBlockingQueue就是支持排序的Queue。显然一个支持阻塞的排序Queue要比一个非... 阅读全文
摘要:
在上一节中详细分析了LinkedBlockingQueue的实现原理。实现一个可扩展的队列通常有两种方式:一种方式就像LinkedBlockingQueue一样使用链表,也就是每一个元素带有下一个元素的引用,这样的队列原生就是可扩展的;另外一种就是通过数组实现,一旦队列的大小达到数组的容量的时候就将... 阅读全文
摘要:
在《并发容器 part 4 并发队列与Queue简介》节中的类图中可以看到,对于Queue来说,BlockingQueue是主要的线程安全版本。这是一个可阻塞的版本,也就是允许添加/删除元素被阻塞,直到成功为止。BlockingQueue相对于Queue而言增加了两个操作:put/take。下面是一... 阅读全文
摘要:
ConcurrentLinkedQueue是Queue的一个线程安全实现。先来看一段文档说明。一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列获取操作从队列头... 阅读全文
摘要:
Queue是JDK 5以后引入的新的集合类,它属于Java Collections Framework的成员,在Collection集合中和List/Set是同一级别的接口。通常来讲Queue描述的是一种FIFO的队列,当然不全都是,比如PriorityQueue是按照优先级的顺序(或者说是自然顺序... 阅读全文