转载

Java并发编程的艺术(十一)——倒计时器、同步屏障、信号量

当多个线程需要执行时,若其中一个或多个线程需要等待其他线程完成某些操作后才能执行,则可用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()方法表示释放许可证。
原文  https://juejin.im/post/5d1378a0f265da1bc552740a
正文到此结束
Loading...