Monthly Archive: 7月 2016

Concurrency: New Library Components (1)

Java SE5中加入的java.util.concurrent包含了很多用于解决并发问题的新类。 1. CountDownLatch   创建CountDownLatch时需要指定一个初始的计数,在任务中调用CountDownLatch对象的await()会阻塞任务,直到CountDownLatch的计数为零。其他任务可以(在自己的工作完成后)调用CountDownLatch对象的countDo…
Read more

Concurrency: Deadlock

  Edsger Dijkstra提出的Dining Philosophers是死锁(Deadlock)的一个经典问题。五个哲学家坐在一张圆桌周围,桌子中间放了一盆面条,哲学家们时而思索,时而吃面。哲学家思索的时候互不妨碍,吃面的时候需要使用两把叉子。叉子只有五把,相邻两个哲学家之间放有一把。吃面时,哲学家只会使用与他相邻的左边和右边的两把叉子,如果叉子被其他人使用,则哲学家就会耐心等待别人用完,…
Read more

Concurrency: Cooperation Between Tasks (2)

4. Producer-Consumers and Queues   java.util.concurrent.BlockingQueue接口定义了一种同步队列,同一时间只允许一个任务对队列进行插入和删除。BlockingQueue有多种标准实现,LinkedBlockingQueue提供不限长度的队列,ArrayBlockingQueue具有固定长度。如果队列为空,试图从该队列中获取元素的任务会…
Read more

Concurrency: Cooperation Between Tasks (1)

  使用wait()、notifyAll(),以及Java SE 5中引入的await()和signal(),可以控制任务的运行,实现任务间的协作。 1. wait() and notifyAll()   wait()会让任务挂起,与sleep()不同的是,wait()会解除当前所占用的对象的锁定,并会被notify()或notifyAll()唤醒,wait()结束前会重新获得进入wait()时所…
Read more

混用同步块和同步方法时的问题

  在Thinking in Java (Fourth Edition)的Concurrency一章的Critical Sections 一节中有一个例子,用于展示同步整个方法和手动给代码块加锁两种同步方式的差异。   例子中定义了Pair具有x和y两个字段,要求x和y必须始终保持相同。checkState()会检查x和y是否相同,如不相同则抛出异常。 class Pair { // Not th…
Read more

Concurrency: Sharing Resources (2)

3 Atomicity and Volatility   原子操作(Atomic Operation)指的是不会被线程调度打断的操作。对除了long和double以外基本类型的简单操作(如赋值和返回值)是原子性的。JVM允许以两次32位操作的形式读写64位的值(long和double型变量),导致读写期间可能发生上下文切换。为了使long和double得到原子性,可以使用volatile来修饰lo…
Read more

Concurrency: Sharing Resources (1)

1. Improperly accessing resources   考虑这样一个例子:一个任务产生偶数序列,另外一个任务检查第一个任务产生的数字是否为偶数。   定义抽象类IntGenerator作为所有偶数序列生成器的基类: public abstract class IntGenerator { private volatile boolean canceled = false; publ…
Read more