gpt4 book ai didi

java - 我能以更好的方式加入线程吗?

转载 作者:行者123 更新时间:2023-11-29 05:46:39 25 4
gpt4 key购买 nike

假设我在一个程序中有多个 Runnable 实例,所有实例都由一个 Executor 实例调度。此外,假设我在某个时候需要等待这些可运行的子集完成后再继续。

我可以这样做的一种方法如下:

public abstract class Joinable implements Runnable {

private final Semaphore finishedLock = new Semaphore(1);

@Override
public final void run() {
try {
finishedLock.acquireUninterruptibly();
doWork();
} finally {
finishedLock.release();
}
}

public abstract void doWork();

public void join() {
finishedLock.acquireUninterruptibly();
}
}

然后,实现类可以简单地覆盖 doWork(),而不是 run(),以定义在执行期间应该做什么。

加入过程将如下所示:

void doStuff() {

Executor executor = Executors.newCachedThreadPool();

List<Joinable> joinables = new LinkedList<Joinable>();
// Fill joinables with implementors of Joinable...

List<Runnable> others = new LinkedList<Runnable>();
// Fill others with implementors of Runnable...

for(Joinable joinable : joinables)
executor.execute(joinable);

for(Runnable runnable : others)
executor.execute(runnable);

for(Joinable joinable : joinables)
joinable.join();

// Continue, no matter what the threads in others are up to.
}

这是解决这个问题的好方法(甚至安全吗?),还是有更好的方法?

最佳答案

您当前的解决方案不是线程安全的。无法保证在您调用 join 之前,执行程序会在您的 Joinable 上调用 run。因此,在某些情况下,您的主线程将在 Joinable 之前获取锁。

如果您知道可连接的总数N,则可能的解决方案是使用CountDownLatch,您创建一个CountDownLatch(N) 并将其传递给每个实例。当每个 joinable 完成时,让它调用 countDown()。您的主线程在闩锁上调用 await()await() 在闩锁计数为 0 之前不会返回。

关于java - 我能以更好的方式加入线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15647075/

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