代码之家  ›  专栏  ›  技术社区  ›  Markus

倒计时屏障

  •  0
  • Markus  · 技术社区  · 7 年前

    我希望在Java并发世界中找到一个倒计时障碍/同步:我希望有一个允许线程的类 acquire() 全面的 n 次和次障碍块 t

    Semaphore 无法解决问题,因为需要阻塞所有线程。我想这可以通过一个 ReentrantLock compare and swap (CAS)。CountDownLatch不够,因为我想在达到条件后重置计数。

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

    1 回复  |  直到 7 年前
        1
  •  0
  •   Markus    7 年前

    我提出了这个实现:

    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