CountDownLatch workDone = new CountDownLatch(6);
workDone.countDown(); // mark an event
workDone.await(); // wait until the counter reaches zero
Even if latches also refer to another concept, it's still positive to see some naming consistency across languages. What name would you have preferred?[1] https://docs.oracle.com/en/java/javase/11/docs/api/java.base...
A latch is a circuit that takes on a value (high or low, 1 or 0) when some some gating signal arrives (like a clock pulse) and then holds that value after the input is removed.
It is named after a door latch; a door latches when you close it and then holds that state: you can't pull it open again without using the handle/knob.
If something is called "latch" which does not change its state once in order to reflect an input event, and then hold that state until explicitly recent, then it's misnamed due to abusing the metaphor.
The barrier metaphor is the right one for an object that is hit some predetermined number of times and then fires an event (like releasing some waiting thread(s)). That predetermined number of events is its "barrier potential": the threshold that must be met to break through the barrier.
"There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors."
[0] https://docs.oracle.com/en/java/javase/15/docs/api/java.base...
This contrasts to std::barrier which auto-resets once signaled[1].
As such I think it would be better if they had called it std::latched_barrier or similar.
Too bad they couldn't qualify it somewhere further down below std::. Something like std::thread::barrier or similar might be easier to understand.
Edit: Ok so a (Windows) event is one bit, a C++ latch is a one-shot counter, and a C++ barrier is a cyclic counter. But I thought a barrier in general computer science terms is just a one-shot counter, which is what they're calling a latch in C++?
class ThreadLatch
{
public:
ThreadLatch(std::size_t count = 0)
: _count(count) {}
void inc()
{
std::lock_guard<std::mutex> lock(_mutex);
++_count;
}
void dec()
{
std::lock_guard<std::mutex> lock(_mutex);
assert(0 != _count);
--_count;
if(0 == _count)
{
_condition.notify_all();
}
}
void wait()
{
std::unique_lock<std::mutex> lock(_mutex);
while(_count > 0)
{
_condition.wait(lock);
}
}
private:
std::mutex _mutex;
std::condition_variable _condition;
std::size_t _count;
};A latch allows one or more threads to wait until a set of operations being performed in other threads completes [0].
[0] https://docs.oracle.com/javase/8/docs/api/java/util/concurre...
A barrier (what this thing is) blocks threads until the counter reaches zero.
ws.Add(1)
[...]
wg.Done()
in Go?[0]: https://docs.oracle.com/javase/7/docs/api/java/util/concurre...
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/co...
Before this stuff landed, Java's concurrency model was a lot less nice to deal with. Good high level abstractions are important. Nice to see the same kind of primitives are being added to C++.
Several other C++ libraries also provided condition variables, which latches are a variant of, along with barriers and flex_latches.
"I enjoyed programming in Java, and being relieved of the responsibility for producing a quality product."