CountDownLatch 대 세마포
사용의 이점이 있습니까?
java.util.concurrent.CountdownLatch
대신에
java.util.concurrent.Semaphore ?
내가 말할 수있는 한 다음 조각은 거의 동일합니다.
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 번 경우를 제외하고는 래치를 재사용 할 수 없으며 더 중요한 것은 생성 될 스레드 수를 미리 알아야합니다 (또는 래치를 생성하기 전에 모두 시작될 때까지 기다려야합니다).
그렇다면 어떤 상황에서 래치가 더 좋을까요?
CountDown 래치는 예제와 정반대로 자주 사용됩니다. 일반적으로 countown이 0에 도달하면 동시에 시작되는 "await ()"에서 많은 스레드를 차단합니다.
final CountDownLatch countdown = new CountDownLatch(1);
for (int i = 0; i < 10; ++ i){
Thread racecar = new Thread() {
public void run() {
countdown.await(); //all threads waiting
System.out.println("Vroom!");
}
};
racecar.start();
}
System.out.println("Go");
countdown.countDown(); //all threads start now!
You could also use this as an MPI-style "barrier" that causes all threads to wait for other threads to catch up to a certain point before proceeding.
final CountDownLatch countdown = new CountDownLatch(num_thread);
for (int i = 0; i < num_thread; ++ i){
Thread t= new Thread() {
public void run() {
doSomething();
countdown.countDown();
System.out.printf("Waiting on %d other threads.",countdown.getCount());
countdown.await(); //waits until everyone reaches this point
finish();
}
};
t.start();
}
That all said, the CountDown latch can safely be used in the manner you've shown in your example.
CountDownLatch is used to start a series of threads and then wait until all of them are complete (or until they call countDown()
a given number of times.
Semaphore is used to control the number of concurrent threads that are using a resource. That resource can be something like a file, or could be the cpu by limiting the number of threads executing. The count on a Semaphore can go up and down as different threads call acquire()
and release()
.
In your example, you're essentially using Semaphore as a sort of CountUPLatch. Given that your intent is to wait on all threads finishing, using the CountdownLatch
makes your intention clearer.
Short summary:
Semaphore and CountDownLatch serves different purpose.
Use Semaphore to control thread access to resource.
Use CountDownLatch to wait for completion of all threads
Semaphore definition from javadocs:
A Semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it. Each release() adds a permit, potentially releasing a blocking acquirer.
However, no actual permit objects are used; the Semaphore just keeps a count of the number available and acts accordingly.
How does it work ?
Semaphores are used to control the number of concurrent threads that are using a resource.That resource can be something like a shared data, or a block of code (critical section) or any file.
The count on a Semaphore can go up and down as different threads call acquire
() and release
(). But at any point of time, you can't have more number of threads greater than Semaphore count.
Semaphore Use cases:
- Limiting concurrent access to disk (this can kill performance due to competing disk seeks)
- Thread creation limiting
- JDBC connection pooling / limiting
- Network connection throttling
- Throttling CPU or memory intensive tasks
Have a look at this article for semaphore uses.
CountDownLatch definition from javadocs:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
How does it work?
CountDownLatch works by having a counter initialized with number of threads, which is decremented each time a thread complete its execution. When count reaches to zero, it means all threads have completed their execution, and thread waiting on latch resume the execution.
CountDownLatch Use cases:
- Achieving Maximum Parallelism: Sometimes we want to start a number of threads at the same time to achieve maximum parallelism
- Wait N threads to completes before start execution
- Deadlock detection.
Have a look at this article to understand CountDownLatch concepts clearly.
Have a look at Fork Join Pool at this article too. It has some similarities to CountDownLatch.
Say you walked in to golf pro shop, hoping to find a foursome,
When you stand in line to get a tee time from one of the pro shop attendants, essentially you called proshopVendorSemaphore.acquire()
, once you get a tee time, you called proshopVendorSemaphore.release()
.Note: any of the free attendants can service you, i.e. shared resource.
Now you walk up to starter, he starts a CountDownLatch(4)
and calls await()
to wait for others, for your part you called checked-in i.e. CountDownLatch
.countDown()
and so does rest of the foursome. When all arrive, starter gives go ahead(await()
call returns)
Now, after nine holes when each of you take a break, hypothetically lets involve starter again, he uses a 'new' CountDownLatch(4)
to tee off Hole 10, same wait/sync as Hole 1.
However, if the starter used a CyclicBarrier
to begin with, he could have reset the same instance in Hole 10 instead of a second latch, which use & throw.
Looking at the freely available source, there is no magic in the implementation of the two classes, so their performance should be much the same. Choose the one that makes your intent more obvious.
CountdownLatch makes threads wait on the await() method, until such a time as the count has reached zero. So maybe you want all your threads to wait until 3 invocations of something, then all the threads can go. A Latch generally can not be reset.
A Semaphore allows threads to retrieve permits, which prevents too many threads from executing at once, blocking if it cannot get the permit(s) it requires to proceed. Permits can be returned to a Semaphore allowing the other waiting threads to proceed.
참고URL : https://stackoverflow.com/questions/184147/countdownlatch-vs-semaphore
'code' 카테고리의 다른 글
.NET 콘솔에서 JSON WebService를 호출하는 가장 좋은 방법 (0) | 2020.09.09 |
---|---|
"gdb가 코드 서명되었는지 확인하십시오-taskgated (8) 참조"-홈브류 코드 서명으로 gdb를 설치하는 방법은 무엇입니까? (0) | 2020.09.09 |
bash의 변수에 개행을 삽입하려고 시도 함 (0) | 2020.09.09 |
Java JTable 설정 열 너비 (0) | 2020.09.08 |
github의 이슈를 다른 저장소로 어떻게 옮기나요? (0) | 2020.09.08 |