AQS在几个同步工具类使用
Semaphore
Semaphore 是只允许一定数量的线程同时执行一段任务。
信号量Semaphore的主要作用是来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。 Semaphore只是计数,不包括许可对象,并且Semaphore也不会把许可与线程对象关联起来,因此一个线程中获得的许可可以在另外一个线程中释放。
Semphore对外的两个方法是 acquire()和release()方法。
在许可可用前会阻塞每一个acquire(),然后再获取该许可。
每调用 release()添加一个许可,释放一个正在阻塞的获取者。
总结:在Semaphore中使用AQS的子类Sync,初始化state表示许可数,在每一次请求acquire()一个许可都会导致计数器减少1,同样每次释放一个许可release()都会导致计数器增加1。一旦达到了0,新的许可请求线程将被挂起。
CountDownLatch
等待一组线程执行完后,在来执行这个线程。
a) 当前线程latch.await()后当前线程阻塞。
b) 其他一组线程每执行完后调用latch.countDown();
c) 当count=0时,返回到当前调用latch.await()处继续执行。
CountDownLatch的两个重要方法是await和countDown方法
a) 一种同步机制来保证一个或多个线程等待其他线程完成。
b) 初始化了一个count计数,当count未递减到0时候,每次调用await方法都会阻塞。
c) 每次调用countDown来使count递减。
d) Count=0时,返回到await方法处,开始执行后续的内容。
CyclicBarrier
一组线程等待至某个状态之后(即一组内所有线程都执行到await处)再全部同时执行。
a) 一组线程中每个线程执行到线程方法中的await出后阻塞。
b) 待一组线程都到了这个位置后,唤醒全部线程,继续执行后续内容。
它主要的方法就是一个:await()。
1) await() 方法没被调用一次,计数便会减少1,并阻塞住当前线程。
2) 当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。
3) 在这之后,如果再次调用 await() 方法,计数就又会变成 N-1,新一轮重新开始。
CyclicBarrier 和 CountDownLatch 在用法上的不同
1) CountDownLatch 适用于一组线程和另一个主线程之间的工作协作。即一个主线程等待一组工作线程的任务完毕才继续它的执行是使用 CountDownLatch 的主要场景
2) CyclicBarrier 用于一组需要在一个时间点上达成一致。
3) 另外,CyclicBarrier 的循环特性和构造函数所接受的 Runnable 参数也是 CountDownLatch 所不具备的。
ReentrantLock
ReentrantLock中定义的构造器分为公平的构造器和非公平的构造器。
其中state状态位表示当前持有锁的线程的重入次数。
在获取锁时:
a) 使用AQS的tryAcquire(intarg)方法,如果没有线程持有则立即返回,并设置state为1;
b) 如果当前线程已经占有锁,则state加1;
c) 如果其他线程占有锁,则当前线程不可用。
释放锁时:
a) 使用AQS的tryRelease(intarg),在该方法中主要作用是state状态位减少release个,表示释放锁。
b) 如果更新后的state为0,表示当前线程释放锁,
c) 如果不为0,表示持有锁的当前线程重入数减少