Semaphore信号量
- 信号量可以指定多个线程同时访问某一个资源。而synchronized和重入锁ReentrantLock都只允许一个线程访问一个资源。
- 构造函数
public Semaphore(int permits)
public Semaphore(int permits, boolean fair)
- 常用方法
public void acquire throws InterruptedException()
public void acquireUninterruptibly()
public boolean tryAcquire()
public boolean tryAcquire(long timeout, TimeUnit unit)
public void release()
- 信号量泄露——申请了信号量,而在离开的时候没有释放release();
ReadWriteLock读写锁
- 读读之间不阻塞、其余都阻塞;
- ReadWriteLock读写分离锁,减少锁竞争;
- 系统中,读操作次数远大于写操作,则读写锁就可以发挥更大的功效;
CountDownLatch倒计数器
- 通常用于控制线程等待,可以让某一个线程等待直到倒计数结束,再开始执行;
- 常用方法:
public CountDownLatch(int count)
public void await() throws InterruptedException
public void countDown()
CyclicBarrier循环栅栏
- 与CountDownLatch类似,但是CyclicBarrier的计数器可以循环使用;
- 常用方法:
public CyclicBarrier(int parties, Runnable barrierAction);#计数完成后,执行barrierAction
public int await() throws InterruptedException, BrokenBarrierException
- BrokenBarrierException异常代表当前的CyclicBarrier已经破损了,可能系统已经没有办法等待所有线程到齐了。
LockSupport线程阻塞工具类
- LockSupport可以在线程内任意位置让线程阻塞;
- 与Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出InterruptedException异常;
- 常用方法:
public static void park();
public static void unpark(Thread thread);
- LockSupport类本质使用的使类似信号量的机制,它为每一个线程准备了一个许可(许可默认值是不可用),如果许可可用,那么park()函数会立即返回,并且消费这个许可,如果许可不可用,就会阻塞。而unpark()函数则使得一个许可变为可用。
- 从第四点可以得出,即使unpark操作发生在park之前,它也可以使下一次的park操作立即返回,不会像resume一旦发生在suspend之前就会使得线程永久性挂起。