1.
@Data public abstract class BaseLatch { private int limit; protected int running; BaseLatch(int limit) { this.limit = limit; running = limit; } public abstract void await() throws InterruptedException; public abstract void await(long ms) throws InterruptedException, TimeoutException; public abstract void countDown(); } class CountDownLatch extends BaseLatch { public CountDownLatch(int limit) { super(limit); } @Override public void await() throws InterruptedException { synchronized (this) { while (this.running > 0) { this.wait(); } } } @Override public void await(long ms) throws InterruptedException, TimeoutException { Assert.isTrue(ms > 0, "不允许小于0"); final long endTime = System.currentTimeMillis() + ms; synchronized (this) { while (this.running > 0) { long balanceTime = endTime - System.currentTimeMillis(); if (balanceTime <= 0) { throw new TimeoutException(); } this.wait(balanceTime); } } } @Override public void countDown() { synchronized (this) { if (this.running <= 0) { throw new IllegalStateException(""); } this.running--; this.notifyAll(); } } } class LatchTest { public static void main(String[] args) throws InterruptedException { StopWatch stopWatch = new StopWatch(); stopWatch.start(); Work<Integer>[] works = new Work[2]; BaseLatch latch = new CountDownLatch(works.length); for (int i = 0; i < works.length; i++) { works[i] = new Work<Integer>(latch); new Thread(works[i]).start(); } try { latch.await(5000); } catch (TimeoutException ex) { } for (int i = 0; i < works.length; i++) { System.out.println(works[i].getResult()); } stopWatch.stop(); System.out.println("共消耗时间:" + stopWatch.getTotalTimeSeconds() + "秒"); } } class Work<T> extends Thread { private BaseLatch latch; private T result; public Work(BaseLatch latch) { this.latch = latch; } @Override public void run() { try { Random random = new Random(); int ms = random.nextInt(10) + 1; Thread.sleep(1000 * ms); this.result = (T) (Object) ms; } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); } } public T getResult() { return result; } }
2.可能的输出如下
null 2 共消耗时间:5.012秒