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("所有线程执行完毕了");
}
}
你这个实现针对多个线程调用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();
}
}
先说下CountDownLatch典型的使用场景,一般都是先在主线程中创建多个工作线程(调用CountDownLatch.countDown方法),然后在主线程中调用CountDownLatch的await方法等待所有工作线程完成工作。但实际上,上面的使用场景并不是CountDownLatch唯一的一种用法,比如在主线程中创建多个工作线程(会调用CountDownLatch.countDown方法)之后,主线程可以不调用CountDownLatch.await方法来阻塞主线程,而是创建另一组工作2线程,每个工作2线程中都调用CountDownLatch.await方法阻塞自己,当第一组工作线程(调用CountDownLatch.countDown方法)全部完成之后会唤醒所有的工作2线程。这样就清楚了,所有调用CountDownLatch.await方法的线程是共享锁的。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。