[@talishboy][¥20]CountDownLatch 是否可以使用独占锁来实现?-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

[@talishboy][¥20]CountDownLatch 是否可以使用独占锁来实现?

2018-11-30 21:58:13 1981 2

JDK1.8的源码里面是采用AQS共享锁实现的。为什么不采用独占锁的方式实现?下面附上我独占锁实现的代码:

public class MyCountDownLatch {
    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;
        Sync(int count) {
            setState(count);
        }
        int getCount() {
            return getState();
        }
        protected boolean tryAcquire(int acquires) {
            return (getState() == 0) ? true :false;
        }
        protected boolean tryRelease(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }
    private final MyCountDownLatch.Sync sync;
    public MyCountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new MyCountDownLatch.Sync(count);
    }
    public void await() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }
    public void countDown() {
        sync.release(1);
    }

    public long getCount() {
        return sync.getCount();
    }

    public String toString() {
        return super.toString() + "[Count = " + sync.getCount() + "]";
    }

    public static void main(String[] args) throws InterruptedException {
        MyCountDownLatch myCountDownLatch = new MyCountDownLatch(5);
        for(int i=0;i<5;i++){
            new Thread(()-> {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"start");
                myCountDownLatch.countDown();;
            }).start();
        }
        myCountDownLatch.await();
        System.out.println("所有线程执行完毕了");

    }
}
取消 提交回答
全部回答(2)
  • 1607616329964517
    2019-07-24 08:43:21

    你这个实现针对多个线程调用await情况,无法唤醒所有线程. 不知道理解有没有问题? 我通过模仿ReentrantLock实现了一个独占访问的代码

    public class MyCountDownLatch {
    
    
        private final Sync sync ;
    
    
        public MyCountDownLatch(int state) {
            sync = new Sync(state);
        }
    
        private static final class Sync extends AbstractQueuedSynchronizer {
    
            Sync(int state) {
                setState(state);
            }
    
            @Override
            protected boolean tryAcquire(int arg) {
                return getState() == 0;
            }
            @Override
            protected boolean tryRelease(int arg) {
                for (; ; ) {
                    int c = getState();
                    if (c == 0)
                        return true;
                    int nextc = c - 1;
                    if (compareAndSetState(c, nextc))
                        return nextc == 0;
                }
            }
    
    
        }
    
        public void await() {
            try {
                sync.acquire(1);
            } catch (Exception e) {
    
                e.printStackTrace();
            } finally {
                sync.release(1);
            }
        }
    
        public void countDown() {
            sync.release(1);
        }
    
    
        public static void main(String... args) throws InterruptedException {
    
    
            MyCountDownLatch countDownLatch = new MyCountDownLatch(5);
            Thread thread1 = new Thread() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+":----->1 before await()");
                    countDownLatch.await();
                    System.out.println(Thread.currentThread().getName()+":----->1");
                }
            };
    
            Thread thread2 = new Thread() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+":----->2 before await()");
                    countDownLatch.await();
                    System.out.println(Thread.currentThread().getName()+":----->2");
                }
            };
    
            thread1.start();
            thread2.start();
            Thread.sleep(100);
            System.out.println("start");
            countDownLatch.countDown();
            countDownLatch.countDown();
            countDownLatch.countDown();
            countDownLatch.countDown();
            countDownLatch.countDown();
        }
    }
    
    
    0 0
  • talishboy
    2019-07-17 23:17:52

    先说下CountDownLatch典型的使用场景,一般都是先在主线程中创建多个工作线程(调用CountDownLatch.countDown方法),然后在主线程中调用CountDownLatch的await方法等待所有工作线程完成工作。但实际上,上面的使用场景并不是CountDownLatch唯一的一种用法,比如在主线程中创建多个工作线程(会调用CountDownLatch.countDown方法)之后,主线程可以不调用CountDownLatch.await方法来阻塞主线程,而是创建另一组工作2线程,每个工作2线程中都调用CountDownLatch.await方法阻塞自己,当第一组工作线程(调用CountDownLatch.countDown方法)全部完成之后会唤醒所有的工作2线程。这样就清楚了,所有调用CountDownLatch.await方法的线程是共享锁的。

    0 0
添加回答
相关问答

0

回答

[@talishboy][¥20]阿里云是区块链吗?

2019-04-15 07:08:52 1083浏览量 回答数 0

4

回答

[@talishboy][¥20]如何实现高内聚低耦合的Java编码?

2018-12-16 12:30:01 1764浏览量 回答数 4

2

回答

[@talishboy][¥20]数据库连接池的原理

2018-12-17 16:51:29 2663浏览量 回答数 2

2

回答

[@talishboy][¥20]怎么尽量避免死锁?

2018-12-14 23:47:04 1732浏览量 回答数 2

1

回答

[@talishboy][¥20]你能写出一个正则表达式来判断一个字符串是否是一个数字吗?

2018-12-14 16:55:55 2035浏览量 回答数 1

1

回答

[@talishboy][¥20]怎样更好的实现文件解压缩

2018-12-13 10:16:56 1926浏览量 回答数 1

1

回答

[@talishboy][¥20]Java 中,直接缓冲区与非直接缓冲器有什么区别?

2018-12-14 16:26:56 1636浏览量 回答数 1

1

回答

[@talishboy][¥20]如何合理地估算线程池大小?

2018-12-13 16:23:27 1553浏览量 回答数 1

1

回答

[@talishboy][¥20]zookeeper实现的分布式锁与redis实现的分布式锁之间的区别,如何选取。以及使用中会出现的坑?

2018-12-10 18:14:03 1403浏览量 回答数 1

1

回答

[@talishboy][¥20]zookeeper实现的分布式锁与redis实现的分布式锁之间的区别,如何选取。以及使用中会出现的坑?

2018-12-01 16:39:57 1916浏览量 回答数 1
+关注
0
文章
1
问答
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载