package com.thinker.common.thread;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 练习使用CountDownLatch。
 */
public class TestCountDownLatch {

    private static int wait = 10;
    private static boolean isGone = false;
    private static int carWait = 5;

    public static void main(String[] args) throws IllegalAccessException,
            InstantiationException, InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(wait);
        new Thread(new GetOn(countDownLatch)).start();
        waitGetOn(countDownLatch);
        go();
    }

    private static void waitGetOn(CountDownLatch countDownLatch) throws InterruptedException {
        System.out.println("begin to get on");
        countDownLatch.await(carWait, TimeUnit.SECONDS);
    }

    private static void go() {
        System.out.println("go go");
        isGone = true;
    }

    static class GetOn implements Runnable {

        private CountDownLatch countDownLatch;

        public GetOn(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            for (int i = 0; i < wait; i++) {
                try {
                    if (isGone) {
                        System.out.println("students not go: " + countDownLatch.getCount());
                        break;
                    }
                    boolean goSuccess = new Student(i + 1).geton();
                    if (goSuccess) countDownLatch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (countDownLatch.getCount() != 0) {
                System.out.println("students not go: " + countDownLatch.getCount()) ;
            } else {
                System.out.println("all is well ");
            }
        }
    }

    static class Student {
        private int num;

        public Student(int num) {
            this.num = num;
        }

        public boolean geton() throws InterruptedException {
            Thread.currentThread().sleep(new Random().nextInt(2) * 1000);
            if (isGone) {
                return false;
            }
            System.out.println("student " + num + " get on");
            return true;
        }
    }
}
