What's the point of CountDownLatch in java? [duplicate] - java

This question already has answers here:
CountDownLatch vs. Semaphore
(7 answers)
Closed 6 years ago.
CountDownLatch in java is a high-level synchronization utility which is used to prevent a particular thread to start processing until all threads are ready.
But, Semaphore can totally do the same thing. So, what's the merit of CountDownLatch?
One more question: If CountDownLatch do have some merits, Why It was designed to used only once? I think it's easy to add a set method to reset the count.

Semantically, they're different; and that matters, because it makes your code easier to read. When I see a Semaphore, I immediately start thinking "a limited amount of a shared resource." When I see a CountDownLatch, I immediately start thinking "a bunch of threads waiting for the 'go!' signal." If you give me the former in code that actually needs the latter, it's confusing.
In this sense, a Semaphore being used as a CountDownLatch is a bit like a garden-path sentence; while technically correct, it leads people astray and confuses them.
In terms of more pragmatic uses, a CountDownLatch is just simpler if that's all you need. Simpler is better!
As for reusing a CountDownLatch, that would complicate its usage. For instance, let's say you're trying to queue up threads A, B, and C for some work. You have them await on the latch, and then you release it. Then you reset it, presumably to queue up threads D, E and F for some other work. But what happens if (due to a race condition), thread B hasn't actually been released from the first latch yet? What if it hadn't even gotten to the await() call yet? Do you close the gate on it, and tell it to wait with D, E and F for the second opening? That might even cause a deadlock, if the second opening depends on work that B is supposed to be doing!
I had the same questions you did about resetting when I first read about CountDownLatch. But in practice, I've rarely even wanted to reset one; each unit of "wait then go" (A-B-C, then D-E-F) naturally lends itself to creating its own CountDownLatch to go along with it, and things stay nice and simple.

A Semaphore with n blocks when 0 is reached.
A CountDownLatch of n blocks till 0 is reached. Then all continue at approximately the same time.
So a semaphore is like a gate keeper at the disco, and a count down latch like a start shot at game courses.

Semaphore can totally do the same thing. So, what's the point of CountDownLatch?
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.
Semaphore is blocking the entry to enter critical section and CountDownLatch is blocking the execution of main thread unless other threads complete their tasks.
Have a look at this SE question for more details:
CountDownLatch vs. Semaphore
If CountDownLatch do have some points, Why It was designed to used only once?
If you want to use it repeatedly, use CyclicBarrier
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
Javadocs of CountDownLatch quote that :
A CountDownLatch is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

Related

CPU usage is 100% during Thread.onSpinWait()

I'm writing a backtesting raw data collector for my crypto trading bot and I've run into a weird optimization issue.
I constantly have 30 runnables in an Executors.newCachedThreadPool() running get requests from an API. Since the API has a request limit of 1200 per minute I have this bit of code in my runnable:
while (minuteRequests.get() >= 1170) {
Thread.onSpinWait();
}
Yes, minuteRequests is an AtomicInteger, so I'm not running into any issues there.
Everything works, the issue is that even though I'm using the recommended busy-waiting onSpinWait method, I shoot from 24% CPU usage or so to 100% when the waiting is initiated. For reference I'm running this on a 3900X (24 thread).
Any recommendations on how to better handle this situation?
My recommendation would be to not do busy waiting at all.
The javadocs for Thread.onSpinWait say this:
Indicates that the caller is momentarily unable to progress, until the occurrence of one or more actions on the part of other activities. By invoking this method within each iteration of a spin-wait loop construct, the calling thread indicates to the runtime that it is busy-waiting. The runtime may take action to improve the performance of invoking spin-wait loop constructions.
Note the highlighted section uses the word may rather than will. That means that it also may not do anything. Also "improve the performance" does not mean that your code will be objectively efficient.
The javadoc also implies that the improvements may be hardware dependent.
In short, this is the right way to use onSpinwait ... but you are expecting too much of it. It won't make your busy-wait code efficient.
So what would I recommend you actually do?
I would recommend that you replace the AtomicInteger with a Semaphore (javadoc). This particular loop would be replaced by the following:
semaphore.acquire();
This blocks1 until 1 "permit" is available and acquires it. Refer to the class javadocs for an explanation of how semaphores work.
Note: since you haven't show us the complete implementation of your rate limiting, it is not clear how your current approach actually works. Therefore, I can't tell you exactly how to replace AtomicInteger with Semaphore throughout.
1 - The blocked thread is "parked" until some other thread releases a permit. While it is parked, the thread does not run and is not associated with a CPU core. The core is either left idle (typically in a low power state) or it is assigned to some other thread. This is typically handled by the operating system's thread scheduler. When another thread releases a permit, the Semaphore.release method will tell the OS to unpark one of the threads that is blocked in acquire.

Thread stuck busy waiting under some circumstances and not under others

I'm having a pretty weird problem with a java thread busy-waiting.
I have one thread that busy waits on the state of a static variable of some other thread. Let's say the thread that busy waits is waiting for another thread's static int variable to reach a certain value
while(OtherThread.countInt < 5);
If I use the above code, the thread will be stuck busy-waiting and will not break out of the while loop, even if static int countInt does reach 5.
while(OtherThread.countInt < 5) {
// waste some time doing meaningless work
}
If I use this other code, however, then the thread does break out of the busy-wait loop. Sometimes, as soon as countInt reaches 5, other times a little while after. But it happens. For my particular example, I used this as the "meaningless work"
print("busy waiting...",1000) // wasting time doing meaningless work
where I defined print as synchronzied static void print(String s, int n) that prints string s and then sleeps for n milliseconds.
What gives? Why does the thread get stuck busy waiting on the first code, but not on the other? All threads have same priorities, so it can't be a priority issue.
countInt isn't volatile, therefore the change isn't guaranteed to be visible to the waiting thread.
Since your print() method is synchronized it's likely creating a sufficient memory barrier that the updated value becomes visible to your while loop. This is essentially a coincidence; the while conditional itself is still broken. That's why it's so important to properly design and test concurrent code - it's easy to write something that only appears to work as intended, but will fail later (e.g. under load, on a different processor, after a seemingly-safe refactoring, etc.).
Use a proper memory barrier, such as a synchronised read and write, a volatile field, or a cross-thread communcation mechanism such as those in java.util.concurrent. There are a number of related questions exploring volatile and these other tools.
You'd also do well to study Java's concurrency support. Cross-thread communication is non-trivial.

Making sure a thread's "updates" is readable to other threads in Java

I got one main thread that will start up other threads. Those other threads will ask for jobs to be done, and the main thread will make jobs available for the other threads to see and do.
The job that must be done is to set indexes in the a huge boolean array to true. They are by default false, and the other threads can only set them to true, never false. The various jobs may involve setting the same indexes to true.
The main thread finds new jobs depending on two things.
The values in the huge boolean array.
Which jobs has already been done.
How do I make sure the main thread reads fresh values from the huge boolean array?
I can't have the update of the array be through a synchronized method, because that's pretty much all the other threads do, and as such I would only get a pretty much sequential performance.
Let's say the other threads update the huge boolean array by setting many of it's indexes to true through a non-synchronized function. How can I make sure the main thread reads the updates and make sure it's not just locally cached at the thread? Is there any ways to make it "push" the update? I'm guessing the main thread should just use a synchronized method to "get" the updates?
For the really complete answer to your question, you should open up a copy of the Java Language Spec, and search for "happens before".
When the JLS says that A "happens before" B, it means that in a valid implementation of the Java language, A is required to actually happen before B. The spec says things like:
If some thread updates a field, and then releases a lock (e.g.,
leaves a synchronized block), the update "happens before" the lock is
released,
If some thread releases a lock, and some other thread subsequently
acquires the same lock, the release "happens before" the acquisition.
If some thread acquires a lock, and then reads a field, the
acquisition "happens before" the read.
Since "happens before" is a transitive relationship, you can infer that if thread A updates some variables inside a synchronized block and then thread B examines the variables in a block that is synchronized on the same object, then thread B will see what thread A wrote.
Besides entering and leaving synchronized blocks, there are lots of other events (constructing objects, wait()ing/notify()ing objects, start()ing and join()ing threads, reading and writing volatile variables) that allow you to establish "happens before" relationships between threads.
It's not a quick solution to your problem, but the chapter is worth reading.
...the main thread will make jobs available for the other threads to see and do...
I can't have the update of the array be through a synchronized method, because that's pretty much all the other threads do, and ...
Sounds like you're saying that each worker thread can only do a trivial amount of work before it must wait for further instructions from the main() thread. If that's true, then most of the workers are going to be waiting most of the time. You'd probably get better performance if you just do all of the work in a single thread.
Assuming that your goal is to make the best use of available cycles a multi-processor machine, you will need to partition the work in some way that lets each worker thread go off and do a significant chunk of it before needing to synchronize with any other thread.
I'd use another design pattern. For instance, you could add to a Set the indexes of the boolean values as they're turned on, for instance, and then synchronize access to that. Then you can use wait/notify to wake up.
First of all, don't use boolean arrays in general, use BitSets. See this: boolean[] vs. BitSet: Which is more efficient?
In this case you need an atomic BitSet, so you can't use the java.util.BitSet, but here is one: AtomicBitSet implementation for java
You could instead model this as message passing rather than mutating shared state. In your description the workers never read the boolean array and only write the completion status. Have you considered using a pending job queue that workers consume from and a completion queue that the master reads? The job status fields can be efficiently maintained by the master thread without any shared state concerns. Depending on your needs, you can use either blocking or non-blocking queues.

Barrier break down example

I am reading the book Java Concurrency in Practice where it says,
CyclicBarrier allows a fixed number of parties to rendezvous repeatedly at a barrier point and is useful in parallel iterative algorithms that break down a problem into a fixed number of independent subproblems.
Can someone give an example of how it breaks down a problem into multiple independent subproblems?
You have to break the problem down into multiple independent subproblems yourself.
Barriers ensure that each party completes the first subproblem before any of them start on the second subproblem. This ensures that all of the data from the first subproblem is available before the second subproblem is started.
A CyclicBarrier specifically is used when the same barrier is needed again and again when each step is effectively identical. For example, this could occur when doing any sort of multithreaded reality simulation which is done in steps. The CyclicBarrier would ensure that each thread has completed a given step before all threads will begin the next step.
There is yet another important difference between CountDownLatch and CyclicBarrier and that is: the thread synchronized on CountDownLatch cannot indicate the other threads that something has gone wrong with it, so that the other threads may have a choice to either continue your abort the entire cooperative operation.
In case of a CycliBarrier while one of the threads is waiting on await() some other thread is interrupted or is timed-out, then a BrokenBarrierException will occur on current thread indicating something has gone wrong in one of the cooperating threads.
BrokenBarrierException will also occur in other circumstances which you can find in Javadoc on await() method.
Out-of-the-box, CountDownLatch does not offer this feature.
IF you have an algorithm that can be broken down in independent subproblems,
THEN a CyclicBarrier is useful for all your threads to meet at the end of their calculation and, for example, merge their results.
Note that the Fork/Join framework introduced in Java 7 enables you to do the something similar without needing to use a CyclicBarrier.

Deadlock in a single threaded java program [duplicate]

This question already has answers here:
Is it possible for a thread to Deadlock itself?
(20 answers)
Closed 9 years ago.
Read that deadlock can happen in a single threaded java program. I am wondering how since there won't be any competition after all. As far as I can remember, books illustrate examples with more than one thread. Can you please give an example if it can happen with a single thread.
It's a matter of how exactly you define "deadlock".
For example, this scenario is somewhat realistic: a single-threaded application that uses a size-limited queue that blocks when its limit is reached. As long as the limit is not reached, this will work fine with a single thread. But when the limit is reached, the thread will wait forever for a (non-existing) other thread to take something from the queue so that it can continue.
Before multicore processors became cheap, all desktop computers had single-core processors. Single-core processors runs only on thread. So how multithreading worked then? The simplest implementation for Java would be:
thread1's code:
doSomething();
yield(); // may switch to another thread
doSomethingElse();
thread2's code:
doSomething2();
yield(); // may switch to another thread
doSomethingElse2();
This is called cooperative multithreading - all is done with just 1 thread, and so multithreading was done in Windows 3.1.
Today's multithreading called preemptive multithreading is just a slight modification of cooperative multithreading where this yield() is called automatically from time to time.
All that may reduce to the following interlacings:
doSomething();
doSomething2();
doSomethingElse2();
doSomethingElse();
or:
doSomething();
doSomething2();
doSomethingElse();
doSomethingElse2();
And so on... We converted multithreaded code to single-threaded code. So yes, if a deadlock is possible in multithreaded programs in single-threaded as well. For example:
thread1:
queue.put(x);
yield();
thread2:
x = queue.waitAndGet()
yield();
It's OK with this interlace:
queue.put(x);
x = queue.waitAndGet()
But here we get deadlock:
x = queue.waitAndGet()
queue.put(x);
So yes, deadlocks are possible in single-threaded programs.
Well I dare say yes
If you try to acquire the same lock within the same thread consecutively, it depends on the type of lock or locking implementation whether it checks if the lock is acquired by the same thread. If the implementation does not check this, you have a deadlock.
For synchronized this is checked, but I could not find the guarantee for Semaphore.
If you use some other type of lock, you have to check the spec as how it is guaranteed to behave!
Also as has already been pointed out, you may block (which is different from deadlock) by reading/ writing to a restricted buffer. For instance you write things into a slotted buffer and only read from it on certain conditions. When you can no longer insert, you wait until a slot becomes free, which won't happen since you yourself do the reading.
So I daresay the answer should be yes, albeit not that easy and usually easier to detect.
hth
Mario
Even if your java stuff is single-threaded there are still signal handlers, which are executed in a different thread/context than the main thread.
So, a deadlock can indeed happen even on single-threaded solutions, if/when java is running on linux.
QED.
-pbr
No, Sounds pretty impossible to me.
But you could theoretically lock a system resource while another app locks another that you're going to request and that app is going to request the one you've already locked. Bang Deadlock.
But the OS should be able to sort this thing out by detecting that and give both resources to one app at the time. Chances for this to happen is slim to none, but any good OS should be able to handle this one-in-a billion chance.
If you make the design carefully and only locks one resource at a time, this can not happen.
No.
Deadlock is a result of multiple threads (or processes) attempting to acquire locks in such a way that neither can continue.
Consider a quote from the Wikipedia article: (http://en.wikipedia.org/wiki/Deadlock)
"When two trains approach each other at a crossing, both shall come to a full stop and neither shall start up again until the other has gone."
It is actually quite easy:
BlockingQueue bq = new ArrayBlockingQueue(1);
bq.take();
will deadlock.

Categories

Resources