Concurrency

synchronized and ReentrantLock

ReentrantLock在加锁和内存上提供的语义与内置锁相同,此外它还提供了一些其他功能,包括定时的锁等待、可中断的锁等待、公平性,以及实现非块结构的加锁。ReentrantLock在性能上似乎优于内置锁,其中在Java 6中略有胜出,而在Java 5.0中则是远远胜出。那么为什么不放弃synchronized,并在所有新的并发代码中都使用ReentrantLock?事实上有些作者已经建议这么做,将synchronized作为一种“遗留”的结构,但这会将好事情变坏。

lock() and lockInterruptibly()

在Lock接口中有两个方法,一个是lock方法,一个是lockInterruptibly方法,它们之间具体有什么区别呢?

lock()是拿不到lock就不罢休,不然线程就一直block。lockInterruptibly会优先响应线程中断,处理响应的方式是抛出InterruptedException。

可以参考一下 http://huangyunbin.iteye.com/blog/2013543 ,我也大概看了一下lock和lockInterruptibly的相关源码,但是感觉原博说的有点不太对,不过因为现在没有太多时间深究,可以现从应用的角度来理解即可。原博中举的例子不错,这里就不重复引用了。

TryLock

《Java并发编程实战》这本书的缺点是有些例子给的不完整,所以想直接复制代码、运行看结果还是比较费力的,第13章显示锁的一个例子就是这样。在这种情况下,只能自己写或求助于互联网。下面用网上的一个小例子演示带有超时功能的tryLock的基本用法。关于Lock和同步代码块的区别以及更深入的研究,后续博文会有所涉及。

CountDownLatch and CyclicBarrier

CountDownLatch和CyclicBarrier从字面上理解是“向下数的门闩”和“循环的障碍”,觉得怪怪的,但是即便翻译成更加书面语的“闭锁”或“栅栏”也并不容易理解。《Java并发编程实战》中详细讲解了两者的作用,也举了例子,但理解起来印象不深。如果只是从异同的角度去比较两者,网上倒是有不少文章,但是对于编程实践往往不如通俗的例子来得实在。

ThreadLocal

当访问共享的可变数据时,通常需要使用同步。一种避免使用同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步。这种技术被称为线程封闭,它是实现线程安全性的最简单方式之一。……在Swing中大量使用了线程封闭技术。……线程封闭技术的另一种常见应用是JDBC的Connection对象。

Java语言及其核心库提供了一些机制来帮助维持线程封闭性,例如局部变量和ThreadLocal类,但即便如此,程序员仍然需要负责确保封闭在线程中的对象不会从线程中逸出。

Future

之前在看《Java程序员修炼之道》(主要讲的是Java 7的新特性)的时候就看过并发这块儿,但是感觉看完过段儿时间印象也有点儿模糊。最近重温Java并发编程,拿起了《Java并发编程实战》,只能用四个字儿来形容:干货太多。书里讲的几乎没有废话,大部分例子也都不错,对于理解新的Java并发编程模型很有帮助。不过,也有些例子可能受篇幅所限,讲解的不够细致,所以我就需要从网上再找些相对丰富的例子补充上以加深理解。Future就是其中一例。

What exactly invariant is

invariant到底是什么意思

经常在英文计算机书籍或文章中看到invariant这个词,不过如果要我立刻说出它的意思,我的反应肯定是:一愣。本着对科学认真负责的态度,还是得上网搜索一下,以正视听,哇哈哈。

在著名的问答网站知乎上搜索invariant(s)无果,尝试“不变量”、“不变式”均无果。哼,知乎对计算机科学不够重视啊。在国外著名的问答网站Quora也没找到精确结果,囧;只能求助程序员问答网站Stackoverflow了,Bingo!果然给力,答案在这。为了更清晰地解释这个概念,我把原文翻译成中文如下: