import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args){ // ProgrammerTravleTest.test(); ProgrammerTravleTest.test2(); } } /* 第23章 Latch 设计模式 若干线程并发执行某个特定的任务,然后等到所有的子任务都执行结束之后再统一汇总。 23.2 CountDownLatch程序实现 23.2.1 无限等待的Latch */ class WaitTimeoutException extends Exception{ public WaitTimeoutException(String msg) { super(msg); } } abstract class Latch{ protected int limit; public Latch(int limit) { this.limit = limit; } //该方法会使得当前线程一致等待 public abstract void await()throws InterruptedException; //带超时功能的 public abstract void await(TimeUnit unit, long time) throws InterruptedException,WaitTimeoutException; //当任务线程完成工作之后调用该方法使得计数器减一 public abstract void countDown(); //获取当前还有多少个线程没有完成任务 public abstract int getUnarrived(); } //无限等待CountDownLatch实现 class CountDownLatch extends Latch{ public CountDownLatch(int limit) { super(limit); } @Override public void await() throws InterruptedException { synchronized (this) { while (limit > 0) { this.wait(); } } } /* 这个写法在写改写sysn时用过了。 */ @Override public void await(TimeUnit unit, long time) throws InterruptedException, WaitTimeoutException { if (time < 0) { throw new IllegalArgumentException("The time is invalid."); } long remainingNanos = unit.toNanos(time); final long endNanos = System.nanoTime()+ remainingNanos; synchronized (this) { while (limit > 0) { if (TimeUnit.NANOSECONDS.toMillis(remainingNanos) <= 0) { throw new WaitTimeoutException("The wait time over specify time."); } this.wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos)); remainingNanos=endNanos-System.nanoTime(); } } } @Override public void countDown() { synchronized (this) { if (limit <= 0) { throw new IllegalArgumentException("all of task already arrived"); } limit--; this.notifyAll(); } } @Override public int getUnarrived() { return limit; } } //程序测试齐心协力打开门阀 class ProgrammerTravle extends Thread{ private final Latch latch; private final String programmer; private final String transportation; public ProgrammerTravle(Latch latch, String programmer, String transportation) { this.latch = latch; this.programmer = programmer; this.transportation = transportation; } @Override public void run() { System.out.println(programmer+" start take the transportation["+transportation+"]"); try{ TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(programmer+" arrived by "+transportation); latch.countDown(); } } class ProgrammerTravleTest{ public static void test(){ Latch latch = new CountDownLatch(4); new ProgrammerTravle(latch,"A","a").start(); new ProgrammerTravle(latch,"B","b").start(); new ProgrammerTravle(latch,"C","c").start(); new ProgrammerTravle(latch,"D","d").start(); try { latch.await(); System.out.println("==all of programmer arrived=="); } catch (InterruptedException e) { e.printStackTrace(); } } public static void test2(){ Latch latch = new CountDownLatch(4); new ProgrammerTravle(latch,"A","a").start(); new ProgrammerTravle(latch,"B","b").start(); new ProgrammerTravle(latch,"C","c").start(); new ProgrammerTravle(latch,"D","d").start(); try { latch.await(TimeUnit.SECONDS,5); System.out.println("==all of programmer arrived=="); } catch (InterruptedException e) { e.printStackTrace(); } catch (WaitTimeoutException e) { e.printStackTrace(); } } }
《Java高并发编程详解》笔记