JUC CyclicBarrier with a Semaphore

java.util.concurrent

About CyclicBarrier

CyclicBarrier: Reusable barrier / fence

  1. Similar CountDownLatch (countdown lockout), it blocked a set of threads until the occurrence of an event.
  2. The key difference is that with the lockout, all threads must arrive at the same time the barrier position, in order to continue.
  3. CountDownLatch counter only be used once, and may be used CyclicBarrier counter reset () method to reset
  4. CountDownLatch using down counting mode, CyclicBarrier counting manner using

Source CyclicBarrier

构造函数:

    //线程到达屏障时,优先执行 barrierAction
    public CyclicBarrier(int parties, Runnable barrierAction) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierAction;
    }

    public CyclicBarrier(int parties) {
        this(parties, null);
    }


await(),await(long timeout, TimeUnit unit) :
    方法的线程告诉 CyclicBarrier 自己已经到达屏障,然后当前线程被阻塞,直到:

        1,最后一个线程到达
        2,其他线程中断了当前线程.
        3,其它线程中断了其它等待的线程.
        4,在barrier上面等待的线程发生超时.
        5,其它线程调用了barrier上面的reset方法.

reset()(用于重复利用CyclicBarrier):
    将barrier状态重置。如果此时有线程在barrier处等待,它们会抛出BrokenBarrierException并返回,且这些线程停止等待,继续执行。

    public void reset() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            breakBarrier();   // break the current generation
            nextGeneration(); // start a new generation
        } finally {
            lock.unlock();
        }
    }

CyclicBarrier example

public class CyclicBarrierTest {

    // 自定义工作线程
    private static class Worker extends Thread {
        private CyclicBarrier cyclicBarrier;
        
        public Worker(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
        
        @Override
        public void run() {
            try {
                //线程创建后等待,直到有三个线程才执行后续操作
                cyclicBarrier.await();

                // 工作线程开始处理,这里用Thread.sleep()来模拟业务处理
                System.out.println(Thread.currentThread().getName() + "执行任务!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
    public static void main(String[] args) {
        //三个线程出现才执行
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        
        for (int i = 0; i < 3; i++) {
            Worker worker = new Worker(cyclicBarrier);
            worker.start();
        }
    }
}

About Semaphore

Limit the number of threads can access certain resources, such as by limiting Semaphore.

主要方法:

Semaphore(int permits):
    构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。

Semaphore(int permits,boolean fair):
    构造方法,当fair等于true时,创建具有给定许可数的计数信号量并设置为公平信号量。

void acquire():
    从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。

void acquire(int n):
    从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。

void release():
    释放一个许可,将其返回给信号量。就如同车开走返回一个车位。

void release(int n):
    释放n个许可。

int availablePermits():
    当前可用的许可数

Semaphore Example (Example can achieve single mode)

public class SemaphoreDemo {
    private static final Semaphore semaphore=new Semaphore(3);
    private static final ThreadPoolExecutor threadPool=new ThreadPoolExecutor(5,10,60,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
    
    private static class ThreadDemo extends Thread {

        public void run() {
            try {
                //占位(如果许可数达到最大活动数,那么调用acquire()之后,便进入等待队列,等待已获得许可的线程释放许可)
                semaphore.acquire();
                //执行任务
                Thread.sleep(1000);
                //归还
                semaphore.release();
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        for(int i=0;i<7;i++) {
            Thread t1=new ThreadDemo();
            threadPool.execute(t1);
        }
    }
}

Guess you like

Origin www.cnblogs.com/loveer/p/11514641.html