gpt4 book ai didi

java - ReentrantLock 替代 CountdownLatch

转载 作者:行者123 更新时间:2023-12-02 09:07:53 27 4
gpt4 key购买 nike

我有 myCountDownLatch (按预期工作):

public static void myCountDownLatch() {

CountDownLatch countDownLatch = new CountDownLatch(1);
Thread t = new Thread(() ->
{
try {
log.info("CountDownLatch: in thread..");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
});
t.start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("CountDownLatch: out thread..");
}

我试图理解 CountdownLatchReentrantLock 的区别,并尝试使用 ReentrantLock 重写 myCountDownLatch而不是 CountdownLatch:

public static void myRentrantLock() {

ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();

Thread t = new Thread(() ->
{
try {
log.info("ReentrantLock: in thread..");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});

lock.lock();
t.start();
lock.unlock();

log.info("ReentrantLock: out thread..");
}

我只想在 Thread t 未完成时停止主线程,方法是使用 ReentrantLock 而不是 CountDownLatch

但是,myRentrantLock 的行为与我的 myCountDownLatch 不同。为什么?

最佳答案

您不能用 ReentrantLock 替换倒计时锁存器,ReentrantLock 是一种互斥和通知工具,但您可以使用 ReentrantLock > 实现类似的功能。

它可能看起来像

public class MyLatch {
final ReentrantLock lock = new ReentrantLock();
final Condition zeroReached = lock.newCondition();
int remaining;

MyLatch(int count) {
if(count < 0) throw new IllegalArgumentException();
remaining = count;
}
public void await() throws InterruptedException {
lock.lock();
try {
while(remaining != 0) zeroReached.await();
}
finally {
lock.unlock();
}
}
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
lock.lock();
try {
if(remaining == 0) return true;
long deadLine = System.nanoTime() + unit.toNanos(timeout);
while(remaining != 0) {
final long remainingTime = deadLine - System.nanoTime();
if(remainingTime <= 0) return false;
zeroReached.await(remainingTime, TimeUnit.NANOSECONDS);
}
return true;
}
finally {
lock.unlock();
}
}
public void countDown() {
lock.lock();
try {
if(remaining > 0 && --remaining == 0) zeroReached.signalAll();
}
finally {
lock.unlock();
}
}
public long getCount() {
lock.lock();
try {
return remaining;
}
finally {
lock.unlock();
}
}
}

ReentrantLock 保护内部状态,即 remaining 字段。关联的Condition ZeroReached 用于允许线程等待remaining 字段变为零。

它的使用方式与内置CountDownLatch相同:

public class MyLatchTest {
public static void main(String[] args) {
int num = 10;
MyLatch countDownLatch = new MyLatch(num);
for(int i = 0; i < num; i++) {
Thread t = new Thread(() ->
{
try {
System.out.println("CountDownLatch: in thread..");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("CountDownLatch: one thread finished..");
countDownLatch.countDown();
});
t.start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("CountDownLatch: out thread..");
}
}

请注意,这里不需要显式的Lock,Java 的内在锁定功能也可以工作:

public class MyLatch {
int remaining;

MyLatch(int count) {
if(count < 0) throw new IllegalArgumentException();
remaining = count;
}
public synchronized void await() throws InterruptedException {
while(remaining != 0) wait();
}
public synchronized boolean await(long timeout, TimeUnit unit) throws InterruptedException {
if(remaining == 0) return true;
long deadLine = System.nanoTime() + unit.toNanos(timeout);
while(remaining != 0) {
long remainingTime = deadLine - System.nanoTime();
if(remainingTime <= 0) return false;
wait(remainingTime / 1_000_000, (int)(remainingTime % 1_000_000));
}
return true;
}
public synchronized void countDown() {
if(remaining > 0 && --remaining == 0) notifyAll();
}
public synchronized long getCount() {
return remaining;
}
}

但无论哪种情况,内置的 CountDownLatch 都更高效......

关于java - ReentrantLock 替代 CountdownLatch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59661898/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com