说一说你对CyclicBarrier的理解
【死记硬背】
【概念】CyclicBarrier即循环栅栏,就是一个可以循环利用的屏障。它也是一个同步辅助类,允许两个或者多个线程在某个点上进行同步。
【原理】CyclicBarrier使用一个整形数进行初始化,这个数是需要在某个点上同步的线程数。当一个线程到达指定的点后,它将调用await()方法等待其他的线程。当线程调用await()方法后,CyclicBarrier将阻塞这个线程并使之休眠直到所有其他线程到达。当最后一个线程调用await()方法时,CyclicBarrier对象将唤醒所有在等待的线程,然后这些线程将继续执行。
【性质】CyclicBarrier与CountDownLatch有所不同,它可以被循环重置为初始状态,并把它的内部计数器重置成初始化时的值,而CountDownLatch只能使用一次。
【举例】比如公司组织员工爬山,提前分成了5组,每组6人,当每一组的人到齐后,可以开始爬山,这样可以循环5次,就可以用CyclicBarrier。
【答案解析】
CyclicBarrier的核心方法是await(),有两种方式:// 无参的await() public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen } } // 有参的await() public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException { return dowait(true, unit.toNanos(timeout)); }
下面是同学一起分组去吃饭使用CyclicBarrier的Demo:import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CyclicBarrierTest { private static final int THREAD_NUMBER = 3; private static CyclicBarrier sCyclicBarrier = new CyclicBarrier( THREAD_NUMBER, new Runnable() { @Override public void run() { System.out.println("大家都到达了宿舍楼下,一起出发吧…"); } }); public static void main(String[] args) { ExecutorService executorService = Executors .newFixedThreadPool(THREAD_NUMBER); for (int i = 0; i < THREAD_NUMBER; i++) { executorService.execute(new WalkFromDomitoryToCanteenRunnable( sCyclicBarrier, "同学" + i)); } try { Thread.sleep(3000);// 主线程睡眠 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("CyclicBarrier重用"); for (int i = THREAD_NUMBER; i < THREAD_NUMBER * 2; i++) { executorService.execute(new WalkFromDomitoryToCanteenRunnable( sCyclicBarrier, "同学" + i)); } executorService.shutdown(); } /** * 从宿舍到食堂线程 */ public static class WalkFromDomitoryToCanteenRunnable implements Runnable { private CyclicBarrier mCyclicBarrier; private String mName; public WalkFromDomitoryToCanteenRunnable(CyclicBarrier cyclicBarrier, String name) { this.mCyclicBarrier = cyclicBarrier; this.mName = name; } @Override public void run() { System.out.println(mName + "开始从宿舍出发…"); try { Thread.sleep(1000); mCyclicBarrier.await();// 等待别同学 // 前往食堂 System.out.println(mName + "开始从宿舍楼下出发…"); Thread.sleep(1000); System.out.println(mName + "达到食堂…"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } }
【温馨提示】
点赞+收藏文章,关注我并私信回复【面试题解析】,即可100%免费领取楼主的所有面试题资料!