Two ways of Sequence Printer implementation
题目:两个线程,分别打印[1,3,5]和[2,4,6],写一个程序,打印[1,2,3,4,5,6]。
下面列出两种解法,分别用同步代码块和锁,具体参见程序。
题目:两个线程,分别打印[1,3,5]和[2,4,6],写一个程序,打印[1,2,3,4,5,6]。
下面列出两种解法,分别用同步代码块和锁,具体参见程序。
ReentrantLock在加锁和内存上提供的语义与内置锁相同,此外它还提供了一些其他功能,包括定时的锁等待、可中断的锁等待、公平性,以及实现非块结构的加锁。ReentrantLock在性能上似乎优于内置锁,其中在Java 6中略有胜出,而在Java 5.0中则是远远胜出。那么为什么不放弃synchronized,并在所有新的并发代码中都使用ReentrantLock?事实上有些作者已经建议这么做,将synchronized作为一种“遗留”的结构,但这会将好事情变坏。
在Lock接口中有两个方法,一个是lock方法,一个是lockInterruptibly方法,它们之间具体有什么区别呢?
lock()是拿不到lock就不罢休,不然线程就一直block。lockInterruptibly会优先响应线程中断,处理响应的方式是抛出InterruptedException。
可以参考一下 http://huangyunbin.iteye.com/blog/2013543 ,我也大概看了一下lock和lockInterruptibly的相关源码,但是感觉原博说的有点不太对,不过因为现在没有太多时间深究,可以现从应用的角度来理解即可。原博中举的例子不错,这里就不重复引用了。
《Java并发编程实战》这本书的缺点是有些例子给的不完整,所以想直接复制代码、运行看结果还是比较费力的,第13章显示锁的一个例子就是这样。在这种情况下,只能自己写或求助于互联网。下面用网上的一个小例子演示带有超时功能的tryLock的基本用法。关于Lock和同步代码块的区别以及更深入的研究,后续博文会有所涉及。
CountDownLatch和CyclicBarrier从字面上理解是“向下数的门闩”和“循环的障碍”,觉得怪怪的,但是即便翻译成更加书面语的“闭锁”或“栅栏”也并不容易理解。《Java并发编程实战》中详细讲解了两者的作用,也举了例子,但理解起来印象不深。如果只是从异同的角度去比较两者,网上倒是有不少文章,但是对于编程实践往往不如通俗的例子来得实在。
当访问共享的可变数据时,通常需要使用同步。一种避免使用同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步。这种技术被称为线程封闭,它是实现线程安全性的最简单方式之一。……在Swing中大量使用了线程封闭技术。……线程封闭技术的另一种常见应用是JDBC的Connection对象。
Java语言及其核心库提供了一些机制来帮助维持线程封闭性,例如局部变量和ThreadLocal类,但即便如此,程序员仍然需要负责确保封闭在线程中的对象不会从线程中逸出。
之前在看《Java程序员修炼之道》(主要讲的是Java 7的新特性)的时候就看过并发这块儿,但是感觉看完过段儿时间印象也有点儿模糊。最近重温Java并发编程,拿起了《Java并发编程实战》,只能用四个字儿来形容:干货太多。书里讲的几乎没有废话,大部分例子也都不错,对于理解新的Java并发编程模型很有帮助。不过,也有些例子可能受篇幅所限,讲解的不够细致,所以我就需要从网上再找些相对丰富的例子补充上以加深理解。Future就是其中一例。
经常在英文计算机书籍或文章中看到invariant这个词,不过如果要我立刻说出它的意思,我的反应肯定是:一愣。本着对科学认真负责的态度,还是得上网搜索一下,以正视听,哇哈哈。
在著名的问答网站知乎上搜索invariant(s)无果,尝试“不变量”、“不变式”均无果。哼,知乎对计算机科学不够重视啊。在国外著名的问答网站Quora也没找到精确结果,囧;只能求助程序员问答网站Stackoverflow了,Bingo!果然给力,答案在这。为了更清晰地解释这个概念,我把原文翻译成中文如下: