同步控制是并发程序必不可少的重要手段。JDK提供了很多多线程控制方法。
-
内部锁
Synchronized
-
重入锁
ReentrantLock
1/2 比较请参考 Synchronized与ReentrantLock比较 -
信号量
Semaphore
允许多个线程同时访问某一个资源 -
读写锁
ReadWriteLock
有效地帮助减少锁竞争,以提高系统性能。读写锁允许多个线程同时读,而考虑到数据完整性,写写操作和读写操作依然是需要相互等待和持有锁的。
在系统中,如果读操作的次数远远大于写操作,则读写锁就可以发挥最大的功效,提高系统的性能。 -
CountDownLatch
一种多线程控制工具类;让某一个线程等待直到倒计时结束,再开始执行。 -
循环栅栏
CyclicBarrier
另外一种多线程并发控制实用工具,也可以实现线程间的等待,且功能比CountDownLatch
更加复杂和强大。
CyclicBarrier
的计数器可以循环使用。比如,假设将计数器设置为10,当凑齐第一批10个线程之后,计数器就会清零,然后接着凑齐下一批10个线程。此外,CyclicBarrier
还可以接收一个参数作为barrierAction
,指定当计数器一次计数完成之后,系统会执行的动作。
CyclicBarrier.await()
方法可能会抛出两个异常。一个是InterruptedException
,也就是在等待过程中,线程被中断,这使得线程在等待是依然可以响应外部紧急事件;另一个异常是CyclicBarrier
特有的BrokenBarrierException
。 一旦遇到这个一次杨,则表示当前的栅栏已经破损了,可能系统已经没有办法等待所有的线程到齐了。例如,第五个线程被中断,它会得到一个InterruptedException
, 而其他9个线程会分别得到BrokenBarrierException
。这个异常可以避免其他9个线程进行永久的、无谓的等待。 -
线程阻塞工具类
LockSupport
,可以在线程内任意位置让线程阻塞。
和Thread.suspend()
相比,它弥补了由于resume()
在前发生,导致线程无法继续执行的情况。和Object.wait()
相比,它不需要先获得某个对象的锁,也不会抛出InterruptedException
异常。
LockSupport
的静态方法park()
可以阻塞当前异常。类似的还有partNanos()
,parkUntil()
等方法实现的限时等待。
参考
《JAVA高并发程序设计》 第三章 JDK并发包
网友评论