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高并发编程详解》笔记

05-11 14:40