1. 倒计时器:CountDownLatch
1.1 使用场景
当多个线程需要执行时,若其中一个或多个线程需要等待其他线程完成某些操作后才能执行,则可用CountDownLatch实现功能。
1.2 例程
public class CountDownLatchTest {
static CountDownLatch c = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(1);
c.countDown();
System.out.println(2);
c.countDown();
}
}).start();
c.await();
System.out.println("3");
}
}
复制代码
1.3 小结
- ●CountDownLatch的计数器只能使用一次。
- ●CountDownLatch的构造函数可设置一个int值作为计数器,每调用一个CountDownLatch的countDown()方法则该计算器减一,当计算器为0时可唤醒等待的线程。
- ●计算器为0时,调用await()方法不会等待阻塞当前线程。
2. 同步屏障:CyclicBarrier
2.1 使用场景
当多个线程到达屏障时将会被阻塞,只有这些线程的最后一个线程到达屏障后,屏障才会开门,所有被屏障拦截的线程才能继续执行,并且该屏障是可重复使用的。
2.2 例程
public class CyclicBarrierTest {
static CyclicBarrier c = new CyclicBarrier(2);
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (Exception e) {
}
System.out.println(1);
}
}).start();
try {
c.await();
} catch (Exception e) {
}
System.out.println(2);
}
}
复制代码
2.3 小结
- ●CyclicBarrier的构造函数可设置一个int值作为线程拦截数,每调用CyclicBarrier的await()方法则该int值将减一并阻塞当前线程,当该值为0时表示所有线程以到达屏障,此时需"放行"所有被拦截的线程。
- ●CyclicBarrier有一个更加高级的构造函数CyclicBarrier(int parties,Runnable barrierAction),表示parties数量的线程在到达屏障时优先执行barrierAction线程。
- ●CyclicBarrier的计数器可用reset()方法重置。
3. 信号量:Semaphore
3.1 使用场景
当有m个线程,n个资源(m > n且每个线程占用一个资源)时,Semaphore可用来控制同时访问资源的线程数量,以保证合理地使用资源。
3.2例程
public class SemaphoreTest {
Semaphore semaphore = new Semaphore(3);
public static void main(String[] args) {
for ( int i=0; i<10; i++ ) {
new Thread( new Runnbale(){
public void run(){
semaphore.acquire();
//这里执行任务代码
semaphore.release();
}
} ).start();
}
}
}
复制代码
3.3 小结
- ●Semaphore的构造函数接受一个int值作为许可证数目(即允许线程执行的数目)。
- ●Semaphore的acquire()方法表示获得许可证,获取许可证失败的线程将无法执行。
- ●Semaphore的release()方法表示释放许可证。