深入理解CountDownLatch之手动实现

最近有人私信博主关于CountDownLatch的源码一些细节,这对于初学者来讲学习CountDownLatch的源码还是比较困难的。为此在看源码时,应该先搞懂该类的用途,在进一步对其源码进行分析,这对看源码的你或许小有帮助,话不多说,为了帮助各位更好理解CountDownLatch是怎么回事,本文提供一个CountDownLatch的简单实现,具体代码如下:

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author jianglinzou
 * @date 2020/1/14 下午13:03
 */
public class ObjectCountDown {


    //初始变量 类似于state
    private AtomicInteger atomicInteger;

    //等待线程的数量
    private AtomicInteger waiters;

    private Object lock = new Object();


    public ObjectCountDown(int value) {
        atomicInteger = new AtomicInteger(value);
        waiters = new AtomicInteger(0);
    }


    public void await() throws InterruptedException {
        int current = atomicInteger.get();//获取当前值
        if (current > 0) { //如果大于0
            synchronized (lock) {
                if (atomicInteger.get() > 0) { //进入同步代码块时,wait时确定state值大于0
//                    waiters.incrementAndGet(); //等待的线程数量+1
                    lock.wait();
//                    waiters.decrementAndGet();
                }

            }
        }
    }


    public void countDown() {
        countDown(1);
    }


    protected void countDown(int value) {

        while (true) {
            int current = atomicInteger.get(); //获取当前值
            int target = current - value;
            if (atomicInteger.compareAndSet(current, target)) {
                break;
            }
        }
        //检查是否达到唤醒条件
        MaybeNotifyAll();
    }


    private void MaybeNotifyAll() {
//        System.out.println(Thread.currentThread().getName() + "countdown success");
        int current = atomicInteger.get();
        if (current <= 0) {
            synchronized (lock) { //进入同步代码块时,确定state小于0

                lock.notifyAll();

            }
        }
    }


}

 

为了确保正确性,我们对该类进行测试,其中一个测试类如下:


/**
 * @author jianglinzou
 * @date 2020/1/14 下午13:24
 */
public class ObjectCountDownTest {


    public static void main(String[] args) throws InterruptedException {

        ObjectCountDown objectCountDown = new ObjectCountDown(3);

        Runnable runnable1 = () -> {
            try {
                Thread.sleep(40);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println("test1");
                objectCountDown.countDown();
            }

//            System.out.println("count down1");
        };

        Runnable runnable2 = () -> {

            try {
//                Thread.sleep(500);
                objectCountDown.await();
                System.out.println("success");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

//            System.out.println("await 2");
        };


        Runnable runnable3 = () -> {
            System.out.println("test3");
            objectCountDown.countDown();
//            System.out.println("count down3");
        };

        Thread thread1 = new Thread(runnable1);
        thread1.setName("1");
        Thread thread2 = new Thread(runnable2);
        thread2.setName("2");
        Thread thread3 = new Thread(runnable3);
        thread3.setName("3");

        thread1.start();
        thread2.start();
        thread3.start();
        System.out.println("test main");
        objectCountDown.countDown();
//        System.out.println("count down");


    }


}

该测试类运行多次,发现控制行中,success总是最后输出,符合预期结果,其他测试类就不一一列出,本人自测后均无误,基本验证该类的安全性。由此跟CountDownLatch 功能类似的类已实现完成

 

发布了72 篇原创文章 · 获赞 16 · 访问量 3万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览