倒数障碍

时间:2017-08-08 13:05:14

标签: java java-7 countdown java.util.concurrent barrier

我希望在Java并发世界中找到倒计时障碍/同步:我希望有一个让线程acquire()整体 n次的类而且比t秒(睡眠)的障碍块。

在延迟/休眠之后,应该进一步处理线程。 Semaphore无法解决问题,因为需要阻止所有线程。我认为可以使用ReentrantLockcompare and swap(CAS)实现更好。 CountDownLatch是不够的,因为我想在达到条件后重置计数。

你能在Java 7 +中给我一个暗示吗?

1 个答案:

答案 0 :(得分:0)

我想出了这个实现:

public class CountDownBarrier {
    //public static final Logger LOG = LogManager.getLogger(CountDownBarrier.class);
    protected int cnt;
    protected int currCnt;
    protected int sleep;

    protected ReentrantLock lock = null;
    //protected Condition cond = null;

    public CountDownBarrier(int cnt, int sleep) {
        this.cnt = cnt;
        this.currCnt = cnt;
        this.sleep = sleep;

        lock = new ReentrantLock();
        //cond = lock.newCondition();
    }

    public void acquire() throws InterruptedException {
        lock.lock();
        try {
            if(currCnt <= 0) {
                //LOG.info("Sleep starts ###################################");
                Thread.sleep(sleep);
                currCnt = cnt;
                //LOG.info("Sleep is over ###################################");
            }
            currCnt--;
        } finally {
            lock.unlock();
        }
    }
}

我的测试用例如下:

public class CountDownBarrierTest {
    public static final Logger LOG = LogManager.getLogger(CountDownBarrierTest.class);
    public static int ITER = 5;

    @Test
    public void test1() throws InterruptedException {
        LOG.info("CountDownBarrierTest.test1()");
        CountDownBarrier barrier = new CountDownBarrier(4, 5000);

        List<Thread> tList = new ArrayList<Thread>();
        for(int i = 0; i < 3; i++) {
            TheAction x = new TheAction(i, barrier);
            tList.add(new Thread(x));
        }

        LOG.info("Start all threads");
        for(Thread t : tList) {
            t.start();
        }

        for(Thread t : tList) {
            t.join();
        }
        LOG.info("All threads finished");
    }

    private class TheAction
    implements Runnable {       
        private int id;
        private CountDownBarrier barrier;

        public TheAction(int id, CountDownBarrier barrier) {
            this.id = id;
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                for(int i = 0; i < ITER; i++) {
                    barrier.acquire();
                    LOG.info("#" + id + ": Action!!");
                    Thread.sleep(1000);
                    //LOG.info("#" + id + ": ------------");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

输出可能如下所示:

15:38:46.926 [main] [INFO] CountDownBarrierTest - CountDownBarrierTest.test1()
15:38:46.933 [main] [INFO] CountDownBarrierTest- Start all threads
15:38:46.934 [Thread-1] [INFO] CountDownBarrierTest$TheAction - #0: Action!!
15:38:46.934 [Thread-2] [INFO] CountDownBarrierTest$TheAction - #1: Action!!
15:38:46.934 [Thread-3] [INFO] CountDownBarrierTest$TheAction - #2: Action!!
15:38:47.934 [Thread-1] [INFO] CountDownBarrierTest$TheAction - #0: Action!!
15:38:47.934 [Thread-3] [INFO] CountDownBarrier - Sleep starts ###################################
15:38:52.935 [Thread-3] [INFO] CountDownBarrier - Sleep is over ###################################
15:38:52.935 [Thread-3] [INFO] CountDownBarrierTest$TheAction - #2: Action!!
15:38:52.935 [Thread-1] [INFO] CountDownBarrierTest$TheAction - #0: Action!!
15:38:52.935 [Thread-2] [INFO] CountDownBarrierTest$TheAction - #1: Action!!
15:38:53.935 [Thread-1] [INFO] CountDownBarrierTest$TheAction - #0: Action!!
15:38:53.935 [Thread-3] [INFO] CountDownBarrier - Sleep starts ###################################
15:38:58.935 [Thread-3] [INFO] CountDownBarrier - Sleep is over ###################################
15:38:58.935 [Thread-3] [INFO] CountDownBarrierTest$TheAction - #2: Action!!
15:38:58.935 [Thread-2] [INFO] CountDownBarrierTest$TheAction - #1: Action!!
15:38:58.935 [Thread-1] [INFO] CountDownBarrierTest$TheAction - #0: Action!!
15:38:59.935 [Thread-3] [INFO] CountDownBarrierTest$TheAction - #2: Action!!
15:38:59.935 [Thread-2] [INFO] CountDownBarrier - Sleep starts ###################################
15:39:04.936 [Thread-2] [INFO] CountDownBarrier - Sleep is over ###################################
15:39:04.936 [Thread-2] [INFO] CountDownBarrierTest$TheAction - #1: Action!!
15:39:04.936 [Thread-3] [INFO] CountDownBarrierTest$TheAction - #2: Action!!
15:39:05.936 [Thread-2] [INFO] CountDownBarrierTest$TheAction - #1: Action!!
15:39:06.936 [main] [INFO] CountDownBarrierTest - All threads finished