Similarity between sleep and join in java - java

As the question suggests , I want to know the similarity between the sleep and join methods on the thread. I have gone through many questions that describe the difference between the sleep and join method. But I would like to know different scenarios where the sleep and join methods could be used interchangeably . According to my thinking following code should work just in the same way. I have a main thread in which I start a new thread (just 1) and I want the main thread to wait for the new thread to complete for some amount of time. The code is as follows:
newThread.join(10000)
OR,
Thread.sleep(10000)
but , when I run this code I don't get expected results. why is this so? technically it should be the same right?

NO NO NO
sleep and join are completely different.
join will wait for the specified Thread to finish (either normally or abnormally) or until the time expires.
sleep will simply stop the current thread for the specified time.
They are completely different. One explicitly waits for another Thread and wakes the instant that that Thread ends. sleep just stops execution.
If you can guarantee than newThread will take longer then 10,000ms to to complete then they become equivalent, but this is a degenerate case.
If you want to wait for another Thread to complete use join.
If you want your current Thread to stop what it's doing and sleep for a while use sleep.

It's not clear to me what your actual question is, but your third sentence in says, "I would like to know different scenarios where the sleep and join methods could be used interchangeably."
From a practical point of view, if you worked with a team of software developers writing production code, there would be no scenarios in which other developers would permit you to use join(long) as an alternative to sleep(long). No way, no how! It does not matter that there are circumstances under which it would actually work.
Production code should be readable. The intent of the code should be obvious to others. It should obey The Principle of Least Surprise (See Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin). That means, when you write foobar.join(n), you should be expecting the foobar thread to die. You might be prepared to handle the timeout case, but that should be the exception, not the rule. There is no other legitimate reason to call join(n). Anything else would be a "hack", and we do not put hacks in production code.

Related

Why does Sonar recommend avoiding Thread.sleep?

According to this document (rule) S2925
https://rules.sonarsource.com/java/RSPEC-2925
We need to change the Thread.sleep with:
await().atMost(2, Duration.SECONDS).until(didTheThing())
Can someone give me any logical answer why we need to do that?
When this Awaitility class creates thread in the backend. What is the point of this rule?
Here's a logical reason for you:
Thread.sleep(2000);
will block the current thread for at least 2 seconds.
By contrast:
await().atMost(2, Duration.SECONDS).until(didTheThing());
or equivalent code will block the current thread for up to 2 seconds, and will stop waiting when the event occurs.
The latter is more responsive.
The only situation where sleep() might be preferable are where the thread is not waiting for an event related to another Java thread. Even then, sleep may end up waiting longer than you asked for, so it is not suitable for "real time" timing.
This specific warning is in the context of test code, but the advice against using sleep() applies more generally.
I've never come across Awaitility before, but it seems like it is designed to make it easier to write unit tests that entail timing checks. In the example in questions ... it appears that it would have the benefit of making your tests run faster!
And as a commenter pointed out, the documentation for the rule explains the reasoning itself:
Thread.sleep should not be used in tests
Using Thread.sleep in a test is just generally a bad idea. It creates brittle tests that can fail unpredictably depending on environment ("Passes on my machine!") or load. Don't rely on timing. Use mocks or use libraries such as Awaitility for asynchronous testing.

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.

Multithreaded debugging in java

I have a program that runs about 50 threads. I employ a producer consumer design pattern to communicate data between the threads. After the program has been running for a while, sometimes it freezes due to one of the BlockingQueue's I use to distribute data between the threads becomes full, and therefore the main distribution part of the program blocks when it tries to add data to this BlockingQueue. In other words, one of the threads stops for some reason and then the blockingQueue it uses to receive data becomes full.
How do I go about debugging this in an efficient manner? I have tried surrounding the content in all run() methods with catch(Exception e), but nothing is ever thrown. I develop in Java/IntelliJ.
Any thoughts, ideas or general guidelines?
"Debug it" by using a logger. I like SLF4J.
Set up log.debug statements before and after each critical operation. Use log.entering and log.exiting calls at the start and end of each method.
While you are 'debugging' you'll run your application with the logger set to a very low level (FINEST) then run your application and watch the logging statements to learn when it fails and what the state is when it fails.
Since you're worried about a threading issue, make sure your log format includes the thread name or number.
general guidelines?
I don't know if this applies to your situation, but a very important guideline is to never have locks being taken in different orders.
An example:
Thread 1:
ResourceA.lock();
ResourceB.lock();
...
ResourceB.unlock();
ResourceA.unlock();
Thread 2:
ResourceB.lock();
ResourceA.lock();
...
ResourceA.unlock();
ResourceB.unlock();
Now if thread 1 is interrupted when it already owns ResourceA but not yet ResourceB, and thread 2 is allowed to run, thread 2 will take ResourceB. Then thread 1 owns ResourceA and waits for ResourceB, and thread 2 owns ResourceB and waits for ResourceA, so you have a deadlock.

I've been taught that conditions in concurrency do not necessarily need to be written in a loop, against what the oracle doc says

So basically I am learning a bit more serious concurrency (studying how things actually work, instead of just using random stuff if needed).
And my proffesor, when I asked him about this, said me that he and his colleagues hadn't been able to reproduce a spurious wake up, and believes that line is an old line not deleted (like, it was there, java got "better", it's not longer needed, the line is still there), and that is not the case.
Link:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html
It's right below the point called:
Implementation Considerations
In his opinion, a condition that looked kind of like this:
lock.lock()
if (p>q) {
lock.newCondition().await
}
Would be perfectly fine, since he says a spurious wake up can not happen, it wouldn't be needed a loop:
lock.lock()
while (p>q) {
lock.newCondition().await
}
I am MORE than likely mixing things and understanding both the doc and my teacher the wrong way, but I do have spent some time trying to understand why each thing, and can't come with an "answer" of my own, I either believe one or the other (not like it matters, it's pure I-want-to-learn).
My teacher does spend time telling us how explaining concurrency in java it's pretty silly, but I didn't choose it either, so there's that.
Would be perfectly fine, since he says a spurious wake up can not happen, it wouldnt be needed a loop:
Your teacher is wrong for two reasons:
Spurious wakeups do happen. It may not happen on the architecture that they tested on but if you don't take it into account, when you move your application to a different piece of hardware or a different OS revision, you will see problems. It may also be that the spurious interrupts happen occasionally during an exceptional kernel event such as a signal getting delivered at precisely the wrong time. Again, your application may run fine in testing but when you move it into production with a lot higher load, the frequency of the exceptional event may increase...
The underlying problem is that certain native thread implementations may choose to wakeup all conditions associated with an application instead of the specific one that was notified. This is well documented in the javadocs for Object.wait():
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
Here's one example of an architecture that has this limitation. I'll quote from this interesting blog entry:
Internally, wait is implemented as a call to the 'futex' system call. Each blocking system call on Linux returns abruptly when the process receives a signal -- because calling signal handler from kernel call is tricky. What if the signal handler calls some other system function? And a new signal arrives? It's easy to run out of kernel stack for a process. Exactly because each system call can be interrupted, when glibc calls any blocking function, like 'read', it does it in a loop, and if 'read' returns EINTR, calls 'read' again.
The while loop is also very important to protect against race conditions -- especially in multiple thread producer/consumer models. If you have multiple threads that are consuming from a queue (for example), a notification that there are items in the queue may wakeup a thread but by the time it is able to get the lock, another thread has already dequeued the item.
This is well documented on my page here with a sample program that demonstrates the race condition without the use of while.
Producer Consumer Thread Race Conditions
In your example, thread A may be waiting in await() while another thread B may be waiting to get the lock(). Thread C has the lock and is adding to the queue.
// B is here waiting for the lock
lock.lock()
while (p > q) {
// A is here waiting for the signal
lock.newCondition().await();
}
// dequeue
lock.unlock();
Then if the producer adds something to the queue and calls signal() the thread A moves from the WAIT state to the BLOCKED state to get the lock itself. But it may be behind thread B which is already waiting. Once the lock is released, thread B dequeues the element, not thread A. When thread A then gets a chance to dequeue, the queue is empty. Without the while loop, you can get out-of-bounds exceptions or other problems by trying to dequeue from an empty queue.
See my link for more explicit details of the race.
It is still necessary. Your professor is not necessarily incorrect, but has created a strawman argument to knock down.
There are two reasons why you must protect your conditions in a loop.
The first is spurious wake-up. Your professor seems to have been unable to reproduce this, and it may likely not be a problem on the platforms he tests on. This does not mean it is unreproduceable on all platforms.
The second is that between the times that you wake up and actually go to do the logic, the condition may no longer be true. You must guard against this potential race condition. This is also notoriously difficult to reproduce in the lab, and will probably only happen in bizarre circumstances in production.

Another way of Thread.sleep with Do While Loops in Java?

Whenever I write Thread.sleep(500); in my code, it always tells me this sometimes causes problems to use Thread.sleep();. Is there another way to delay time before certain things. If so, can you give me the code and explanation. Thank you
Firstly, you don't show us any code and you don't mention what "it" is. (As in "it always tells me ...".) This makes a specific answer impossible.
It most likely that the problem referred to is that sleep makes your code either wasteful or unresponsive. A common "hack" used to make a thread wait for some condition is to repeatedly call sleep and then test the condition. The problem is that if the condition becomes true while you are sleeping, the thread will still be held up until the sleep interval expires. If you make the sleep interval smaller, then you "burn" more CPU cycles with wakeup / test / sleep iterations.
If you are trying to implement a "wait for some condition to become true", then the efficient way to do it is to either use wait() and notify() (or notifyAll()), or an appropriate higher level synchronization class.
The classic Java pattern is like this:
// waiting for the condition
synchronized (obj) {
while (!condition) {
obj.wait();
}
}
...
// updating the condition ...
synchronized (obj) {
// do something that makes condition true
obj.wait();
}
Note that the use of synchronized is essential if you use wait/notify.
Condition interface can be useful to let other threads notify you about specific events and ask the current thread to get "parked" till then. Condition interface also has a methods called waitUntil(Date deadline) - which causes current thread to wait until the deadline elapses.
Are you waiting for some other thread to perform some activity and wait till then? Use any blocking data structure like BlockingQueue or other advanced synchronizers like CountdownLatch.
If just waiting for some thread to complete its execution use join().
As mentioned bay MadProgrammer and alfasin, its important to know what you are trying to achieve and what is the problem in sleep() you are talking about.
If you want something to happen in the near future, using sleep repeatedly is a bad thing. For once it does not guarantee to be "on time", and for second it can be interrupted at any time, causing your program to malfunction.
If you have one part of your code that needs to be executed repeatedly, using a Timer can solve that perfectly. If you have multiple and different parts of code that need to be executed with given delays, you should use a ScheduledExecutorService. You can either use the ScheduledThreadPoolExecutor directly or - more conveniently - use the ExecutorService.
You can easily circumvent threading issues by just using a single thread. However threading isn't that difficult in Java if you use the right tools.

Categories

Resources