使用有什么好处吗
java.util.concurrent.CountdownLatch
而不是
是吗?
据我所知,以下片段几乎是等效的:
1.信号量
final Semaphore sem = new Semaphore(0);
for (int i = 0; i < num_threads; ++ i)
{
Thread t = new Thread() {
public void run()
{
try
{
doStuff();
}
finally
{
sem.release();
}
}
};
t.start();
}
sem.acquire(num_threads);
2:CountDownLatch
final CountDownLatch latch = new CountDownLatch(num_threads);
for (int i = 0; i < num_threads; ++ i)
{
Thread t = new Thread() {
public void run()
{
try
{
doStuff();
}
finally
{
latch.countDown();
}
}
};
t.start();
}
latch.await();
除了在第2种情况下,锁存器不能被重用,更重要的是,你需要提前知道有多少线程将被创建(或者等到它们都被启动后再创建锁存器)。
那么,在什么情况下,闩锁可能更可取呢?
7条答案
按热度按时间anhgbhbe1#
CountDownLatch
经常用于与你的例子完全相反的情况。通常,你会有很多线程阻塞在await()
上,当计数达到零时,这些线程会同时启动。您还可以将其用作MPI风格的“屏障”,使所有线程在继续之前等待其他线程赶上某个点。
尽管如此,
CountDownLatch
可以安全地以示例中所示的方式使用。8cdiaqws2#
CountDownLatch用于启动一系列线程,然后等待所有线程完成(或者直到它们调用
countDown()
给定次数)。信号量用于控制使用资源的并发线程的数量。该资源可以是类似于文件的东西,也可以是通过限制执行线程数量的cpu。信号量的计数可以随着不同线程调用
acquire()
和release()
而增加和减少。在您的示例中,您实际上是将信号量用作一种CountUPLatch。考虑到您的意图是等待所有线程完成,使用
CountdownLatch
可以使您的意图更清晰。8fq7wneg3#
Semaphore
和CountDownLatch
有不同的用途。1.使用
Semaphore
控制线程对资源的访问。1.使用
CountDownLatch
等待所有线程完成Javadocs中的
Semaphore
定义:Semaphore
维护一组许可证。每个acquire()
在必要时阻塞,直到有一个 permit 可用,然后获取它。每个release()
添加一个许可证,可能会释放一个阻塞的收单方。但是,没有使用实际的许可对象;
Semaphore
仅保持可用数量的计数并相应地动作。信号量用于控制使用资源的并发线程的数量。
当不同的线程调用
acquire()
和release()
时,Semaphore
上的计数可以上下浮动。但是在任何时候,线程数都不能超过信号量计数。Semaphore
使用案例:*1.任务数量,占用大量CPU/内存
1.线程池中的线程数
1.网络中的连接数
Javadocs中的
CountDownLatch
定义:一种同步辅助工具,允许一个或多个线程等待,直到其他线程中正在执行的一组操作完成。
CountDownLatch
的工作原理是有一个计数器初始化线程数,每次线程完成执行时计数器就递减。当计数器达到零时,意味着所有线程都完成了执行CountDownLatch
使用案例:*1.最大并行度
1.在开始执行其他任务之前,等待所有线程完成
1.死锁检测
p1tboqfb4#
假设你走进高尔夫专卖店,想找个四人组,
当你排队从一个专业商店服务员那里得到开球时间时,本质上你叫
proshopVendorSemaphore.acquire()
,一旦你得到开球时间,你叫proshopVendorSemaphore.release()
。任何免费的服务员都可以为您服务,即共享资源。现在你走到起动器,他启动
CountDownLatch(4)
并调用await()
等待其他人,对于你的一部分,你称为签到,即CountDownLatch
。countDown()
,其余的四人也是如此。当所有到达时,起动器给出继续(await()
调用返回)现在,在九洞之后,当你们每个人休息时,假设让先发球员再次上场,他使用“新”
CountDownLatch(4)
开球10洞,与1洞相同的等待/同步。然而,如果启动器使用
CyclicBarrier
开始,他可以在孔10中重置相同的示例,而不是使用& throw的第二个闩锁。jv2fixgn5#
查看免费提供的源代码,这两个类的实现并没有什么魔力,所以它们的性能应该差不多。选择一个使您的意图更明显的类。
5lwkijsr6#
CountdownLatch
使线程等待await()
方法,直到计数达到零。所以也许你想让所有线程等待,直到3次调用某个东西,然后所有线程都可以去。Latch
通常不能重置。Semaphore
允许线程检索许可证,这可以防止太多线程同时执行,如果它无法获得继续执行所需的许可证,则会阻塞。许可证可以返回给Semaphore
,以允许其他等待的线程继续执行。00jrzges7#
信号量通过使用计数器来控制对共享资源的访问。如果计数器大于零,则允许访问。如果计数器为零,则拒绝访问。计数器正在计算允许访问共享资源的许可。因此,要访问资源,线程必须从信号量获得许可。
CountDownlatch使线程等待,直到发生一个或多个事件。countDownLatch最初创建时,会对闩锁释放前发生的事件数进行计数。每次事件发生时,计数都会递减。