我有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..");
}我试图理解CountdownLatch和ReentrantLock的区别,并试图用ReentrantLock而不是CountdownLatch重写myCountDownLatch
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 没有使用ReentrantLock而不是 CountDownLatch**.**完成,I只想停止主线程
但是,myRentrantLock的行为并不等于我的myCountDownLatch。为什么?
发布于 2020-01-09 19:07:16
您不能用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,它的内在锁定特性也能工作:
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都是更有效的…。
https://stackoverflow.com/questions/59661898
复制相似问题