Interviewer: Guy, I heard that you are familiar with JUC source code, and today I will test you on CountDownLatch.

Me: Ok, no problem. (Hem, trying to catch me, let you down)

Interviewer: Please begin your performance

Me:…

CountDownLatch important methods

// the count constructor is the number of counters.A,public CountDownLatch(int count)

// countDown to a shared lock until it reaches 0Second,public void countDown(a)

// Wait in the AQS queue until countDown decreases to 0 before continuingThree,public void await(a)
Copy the code

The important inner class Sync

// Inherit from AQS
private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
            setState(count);
        }

        int getCount(a) {
            return getState();
        }

        // await to determine whether the shared lock is released completely, if it is removed from the queue, continue to implement AQS template method
        protected int tryAcquireShared(int acquires) {
            // Check whether the state synchronization lock is released
            // Release all and continue to execute the await code
            return (getState() == 0)?1 : -1;
        }

        // countDown releases the shared lock and implements the template method of AQS
        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) { // Spin continuously determines whether the state synchronization lock is released
                int c = getState();
                // If state is 0, the synchronization lock has been released.
                // There is no need to do anything, because it was done before
                if (c == 0) 
                    return false;
                // state - 1 releases a synchronization lock
                int nextc = c-1;
                // Use the CAS to set the state synchronization status. If the state is 0, all locks are released
                // The program being await can continue to execute
                if (compareAndSetState(c, nextc))
                    return nextc == 0; }}}Copy the code

Iii. Case examples

The example still uses the meeting example. The boss entered the meeting room and waited for all five people to arrive before the meeting began. So there are two threads where the boss is waiting for the meeting thread and the employee to arrive in the meeting room:

public class CountDownLatchTest {
    private static CountDownLatch countDownLatch = new CountDownLatch(5);

    /** * Boss thread, waiting for employees to arrive for meeting */
    static class BossThread extends Thread{
        @Override
        public void run(a) {
            System.out.println("The Boss is waiting in the conference room." + countDownLatch.getCount() + "Personal meeting...");
            try {
                / / Boss waiting
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("Everyone is here. Let's start..."); }}// The staff arrive at the conference room
    static class EmpleoyeeThread  extends Thread{
        @Override
        public void run(a) {
            System.out.println(Thread.currentThread().getName() + ", to conference room....");
            // The employee arrives at the meeting room count-1countDownLatch.countDown(); }}public static void main(String[] args){
        // The Boss thread starts
        new BossThread().start();

        for(int i = 0,j = countDownLatch.getCount() ; i < j ; i++){
            newEmpleoyeeThread().start(); }}}Copy the code

Four, CountDownLatch constructor (AQS don’t understand, please look at this article blog.csdn.net/hnjsjsac/ar…).

This constructor passes in the number of times the shared lock is required to create CountDownLatch, and the AQS state synchronized lock state is manipulated through the sync object

    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }
Copy the code

Five, the countDown method (AQS don’t understand, please look at this article blog.csdn.net/hnjsjsac/ar…).

Sync. releaseShared is a call to AQS. Sync implements AQS tryReleaseShared and controls how to release the state lock

    public void countDown(a) {
        sync.releaseShared(1);
    }
Copy the code

Six, await method (AQS don’t understand, please look at this article blog.csdn.net/hnjsjsac/ar…).

Sync. AcquireSharedInterruptibly is also called AQS acquireSharedInterruptibly method. Sync simply implements tryAcquireShared to determine whether state is 0 and whether the synchronization lock has been released

    public void await(a) throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
Copy the code

Seven,

1. With the foundation of AQS analysis, the analysis of CountDownLatch is much faster; In fact, CountDownLatch uses AQS shared lock to realize these functions. After understanding AQS shared lock, I understand CountDownLatch 2. Here I briefly summarize some features of CountDownLatch process: • Manage a counter value greater than zero; • For every countDown, state is reduced by 1, until the number of licenses equals 0, all waiting threads in the queue are releasedCopy the code

The interviewer’s face was livid: alas, did not stumped this boy, can only send the offer to him

Me: Offer come, the world I have

 

Follow wechat public account: IT elder brother

Java Foundation, Java Web, JavaEE, including Spring Boot, etc

Reply: Resume template, you can get 100 beautiful resumes

Reply: Java learning route, you can get the latest and most complete a learning roadmap