In some cases, most of us write things like this:
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
; // do nothing
}
Whether right or wrong, acceptable only in some test harnesses, is not my point.
My point is that the same code could be written,more succinctly, as:
LockSupport.parkNanos(2000* 1000000);
is there any reason why I should favour one approach over the other.
Readability: Thread.sleep has a pretty intuitive meaning. How would you describe (to another developer) your use of LockSupport.parkNanos? If that description primarily consists of "I want the current thread to sleep" then surely Thread.sleep is more descriptive.
The conciseness comes from the lack of interrupt handling - so create a wrapper method to do this if you want, which propagates the exception as a RuntimeException. Heck, if you're creating a wrapper method, you can use either implementation, although another thread could of course unpark your "sleeping" thread in the same way as it could interrupt it...
The docs for the method parkNanos provides the conditions in which the method can return. One of those conditions is: the call spuriously (that is, for no reason) returns. So basically it's OK to use it if you don't mind spurious wake-ups and some other Thread "unparking" the waiting thread in consideration. And of course, the comment by Jon pretty much nails the reasoning for preferring one over another.
LockSupport has a much more limited application, and does not support Exception handling. If you have to only lock a single thread, it is OK.
From the API:
these methods are designed to be used as tools for creating
higher-level synchronization utilities, and are not in themselves
useful for most concurrency control applications.
Related
Thread class has many static methods that are called by class name. Some of them are:
But yet, we are provided with method currentThread() that returns currently executing thread object. Some are:
Unfortunately, this created confusion in my head. When I think of a method I want, I have no clue whether I would found it as static or instance. So why did they make such two approaches?
I mean, couldn't they all be grouped in same 'calling'? For example why is sleep() static and not instance method called with Thread.currentThread().sleep()? Another weird example is between interrupted() and isInterrupted() defined in different manner. They do exactly the same thing, just interrupted() additionally clears interrupted flag. Has anyone logic answer to this, so I have no struggle where to find each method?
It's tricky; the answer is different for each method. Let's go through the ones you named:
Thread.sleep
Imagine I called: someOtherThread.sleep(1000L);. What would this mean? Surely that ought to mean: Sleep that other thread, not my thread. Except that's not something java offers: You can sleep your own thread, but you cannot arbitrarily tell some other thread to freeze like they're doing a mime act, mid execution of some arbitrary command. For example, if that thread is currently blocked on, say, waiting for the OS to deliver some bytes from a file read, that definitely cannot just fall asleep, and there are many, many other scenarios where a thread cannot do that.
Thus, java does not offer this functionality - you can't sleep other threads. Only your own. There are two different ways to make this at least somewhat clear in API design:
The first is to have sleep be an instance method (thus, you'd have to write e.g. Thread.currentThread().sleep(1000L);), and spec the method that it will guaranteed, always, immediately throw an IllegalStateException if you invoke it on any thread except your own. This means a compile/write-time detectable error condition would only be caught at runtime (this is bad; catching a problem earlier is obviously better than catching it later), it makes the code you'd have to write to sleep needlessly longer, and the existence of a sleep method you can invoke on thread instances sure suggests that you can sleep other threads. It'd just be crappy API design.
The second is to make sleep static.
Think of it this way: java.lang.Thread is a container for two mostly unrelated batches of methods: One is a set of methods you can use on threads (those'd be the instance methods). The other is a bunch of thread and flow related primitives, such as 'sleep', 'yield', and interrupt interaction. They just happen to be shoved into the same class.
interrupt
This is probably the trickiest. Unlike sleeping, you can in fact ask another thread's interrupt flag status.
The reason there are two methods are because of the more or less intended API design of the interrupt system.
The interrupt system is designed as follows:
If you want some thread to stop what it is doing for some unspecified reason (for example, you want it to re-check some condition, or just cease running, or anything else you can think of) then you need a mechanism to signal this. In particular, you'd want such a mechanism to ensure that any interruptable blocking operations, such as Thread.sleep(100000L) are interrupted. In other words, you can't just say: Whatever, it's up to the code itself, just, um, make an AtomicBoolean and check it a lot.
That's where the 'interrupt' system comes in. The idea is:
To interrupt any thread, raise its interrupt flag, with thatThread.interrupt();
All methods that do interruptable things should check this flag. The procedure is: If it is raised, then [A] clear it, and [B] handle the interruption, doing whatever the programmer intended to happen upon interruption (just stop running, or re-check some condition, re-read some config file, who knows - it's programming, whatever you want it to mean). If you CAN handle the notion of aborting some operation, but you CANNOT handle it, then instead clear that flag and throw InterruptedException, so that the caller can handle it.
As a result, any code that knows what 'I was interrupted!' means should BOTH check the flag (especially if that code has an event loop, which most thread-based code does have), AND catch InterruptedException from any method specced to throw it, and react in the exact same way to either catching that exception or having Thread.interrupted() return true.
Things go all sorts of wrong if you handle the fact that the interrupt flag is up, but you do NOT lower it. For example, if you abort your CPU-bound bitcoin mining or whatnot and just return back to your caller whilst leaving the flag up, then the next time caller invokes Thread.sleep, thread.sleep will notice the flag is up and IMMEDIATELY exit, not sleeping at all (exit by throwing InterruptedException, to be specific). That isn't intended. Hence why it is important that if you respond to an interrupt, you lower that flag.
So, let's go back to API design. There are two strategies:
Hypothetical design A
while (!Thread.currentThread().isInterrupted()) {
mineAnotherBitCoin();
}
Thread.currentThread().clearInterruptFlag();
Design B
while (!Thread.checkAndClearInterruptFlag()) {
mineAnotherBitCoin();
}
Note how design B is conceptually a lot shorter, does not have a 'gap' between checking the flag and clearing it, and therefore is fundamentally less error prone. Furthermore, for, well, reasons, it has been decided that raising an interrupt flag is something you can do to other threads (there is no point interrupting yourself, after all), but clearing one is a thing you can only do to your own thread.
B is what java actually has, except the method is somewhat strangely named interrupted(), and not checkAndClearInterruptFlag(). If you want an explanation of why some methods in java are somewhat suspectly named, it's because java does not like breaking backwards compatibility.
Fundamentally then, while they sound real similar, isInterrupted() and interrupted() do two very different things.
isInterrupted() is to check if some thread has already been interrupted and its response to this interruption is still pending (nothing has yet handled it).
interrupted() is something you put in the condition in your while loops that define the core body of your thread implementation (your 'event loop').
*) It doesn't help that the vast majority of examples of how to make threads in java are erroneous in that they don't properly do this. They tend to be while (true) or while (!running) {} or similar, either ignoring interruptions entirely or with a handrolled interrupt-esque 'running' concept.
So how do I know where to look?
Simple enough: If it's a thing that conceptually doesn't belong to any particular thread (such as 'how many threads are active right now'), or it is a utility concept (such as 'sleep'), or it is a thing that from a VM design principle can only be done to your own thread and not to anything else, then it is a static method in Thread.
If it's a thing that does belong to a particular thread AND the VM would let you do it to other threads (such as interrupting it, asking for its name, id, or priority, getting a stack dump, freezing this thread until the other thread completes, or setting its priority), then it's an instance method.
In many ways you can reverse this logic: If you want to do some thread related business, check the Thread class for something that seems to describe what you want. Then check if the method is static or not. If it is static, you don't get to do it to any other thread (such as clearing the interrupt flag, or sleep). If it's instance, you CAN do that to other threads (such as changing its priority level).
Because you can't make another thread sleep that is not the thread you are on. Even when you call Thread.currentThread().sleep(), you are calling the static method 'sleep'. If you were to call the sleep method on a different Thread object, it would still make the current thread sleep.
If you want to make a different thread sleep, you should set a flag that the other thread reads, which causes it to sleep.
IntelliJ suggests that I replace the deprecated Thread.suspend() with Thread.checkAccess(). Based on the (very brief) documents, checkAccess() seems like a good idea, but also seems quite different than .suspend(), which certainly seems very bad based on the docs. Yet those same docs don't seem to offer a useful alternative to .suspend(), except to suggest that each solution presented has some non-trivial drawbacks.
At the same time, while much better, it seems .checkAccess() relies on there being a SecurityManager implemented, so simply clicking "fix this" also seems like a bad idea without some well-thought-out implementation.
I have made the suggested change, and nothing has broken – yet... But I wonder...
If .checkAccess() is the best alternative, what is the best way to implement it in a nutshell? If it isn't, what is a better alternative?
According to the docs of Thread.suspend:
First, the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException (in the current thread).
If the thread is alive, it is suspended and makes no further progress unless and until it is resumed.
So, invoking checkAccess() is preserving the "safe" part of the suspend() call, in that it will throw an exception if you don't have access, but it won't then proceed to the dangerous deadlocking operation.
I don't precisely know what "suspend" does - I have never used this method, and it is helpfully defined as "Suspends this thread". But if you simply want to wait for something to happen, you could wait on some object:
synchronized (thing) {
thing.wait();
}
then call thing.notify() from the thread you would otherwise be using to resume the thread.
But note that the primitive synchronization methods on Object are inherently difficult to use - for example, Object.wait() may spuriously wake up. You should rarely be using them directly (or Thread, for that matter).
There is a bunch of higher-level synchronization objects in the java.util.concurrent package. For example, you could have a queue shared between your "suspended" and "resuming" threads, where, at the point you want to suspend, one thread waits for the other to put something into the queue.
int capacity = ...
BlockingQueue q = new LinkedBlockingQueue<Element>(capacity);
Now, I do feel mildly ridiculous asking this but I'm not particularly savvy when it comes to java concurrency, so I would appreciate some help with choosing the correct way to enqueue something (and dequeue, actually, but I expect when we cleared up the one, the other will fall into place by itself).
There is, of course
while(!q.offer(e));
But I'm a bit wary of spinning implementations in a multi-threaded environment.
And I can't do
synchronized(q){
while(!q.offer(e))q.wait();
}
either because the wakeup calls will go to internal (private) instances of Condition, meaning this would be a suicide-by-sleeping-pills implementation.
However, I'm also not particularly fond of
try{
q.put(e);
}catch(InterruptedException ex){}
(even though it does seem to be a popular choice in online examples) because although this would do the waiting for me, I know of no reliable way to detect when an exception would force me to try again.
I could do something like
boolean success = false;
do{
try{
q.put(e);
success = true;
}catch(InterruptedException ex){}
}while(!success)
But then I'd end up enqueuing the same element multiple times if the exception takes place in-between the put and the assignment to success.
I could do
boolean success = true;
do{
try{
q.put(e);
}catch(InterruptedException ex){
success = false;
}
}while(!success)
But I remember having read (way back) that you shouldn't rely on exception handling for conditionals (though I can't seem to remember the reason why this is discouraged).
So ... what options do I have? Do I need to spin or is there something more intelligent?
It is not a good practice to catch an InterruptedException as you do since your code won't be responsive to interruption anymore. An InterruptedException is usually thrown by methods that are responsive to interruptions (current Thread being interrupted) such as the methods of type await, wait, join, sleep and many others, this should not be considered as a failure but rather as it really is, a Thread's status change that needs be taken into consideration.
As Brian Goetz explains in Java Concurrency in Practice, I quote:
When your code calls a method that throws InterruptedException, then
your method is a blocking method too, and must have a plan for
responding to interruption. For library code, there are basically two
choices:
Propagate the InterruptedException. This is often the most sensible policy if you can get away with it just propagate the
InterruptedException to your caller. This could involve not catching
InterruptedException, or catching it and throwing it again after
performing some brief activity-specific cleanup.
Restore the interrupt. Sometimes you cannot throw InterruptedException, for instance when your code is part of a
Runnable. In these situations, you must catch InterruptedException
and restore the interrupted status by calling interrupt on the
current thread, so that code higher up the call stack can see that an
interrupt was issued.
So in your case, you should simply use put(E) as it will make the calling thread waits for space to become available if needed and propagate the InterruptedException in order to keep on being responsive to interruptions.
But then I'd end up enqueuing the same element multiple times if the
exception takes place in-between the put and the assignment to
success.
This can simply never happen since an assignment of a boolean will never throw any exceptions (except a NPE in case of an un-boxing). And only methods responsive to interruption can throw such kind of exceptions as explained above which is clearly not the case of an assignment.
The put() implementation would be the correct one, blocking until interrupted or successful. The offer() is a bad idea if all you are doing is spinning (see first comment for disclaimer).
As Nicolas explained, the handling of the InterruptedException is not straightforward and depends a lot on what your other code is doing, but your concern with "if the exception takes place in-between the put and the assignment to success", that can never happen: a blocking call (like put()) can throw that exception, but it cannot occur between put() and the assignment, or at the assignment.
Lastly, there's no need to synchronize on anything. The main idea in many of java.util.concurrent classes is to avoid or abstract away the explicit synchronization.
So a few points from the LinkedBlockingQueue Javadoc:
The put method will only throw exceptions in two circumstances:
The thread is interrupted, in which case you should stop whatever you're doing anyway. See this question for more about InterruptedExceptions.
The element you're inserting is null, which is another bug entirely.
So overall, you can just use put to wait for space to become available. If either of these particular exceptions is thrown, then you shouldn't retry anyway.
while(!anotherThread.isDone());
or
while(!anotherThread.isDone())
Thread.sleep(5);
If you really need to wait for a thread to complete, use
anotherThread.join()
(You may want to consider specifying a timeout in the join call.)
You definitely shouldn't tight-loop like your first snippet does... and sleeping for 5ms is barely better.
If you can't use join (e.g. you're waiting for a task to complete rather than a whole thread) you should look at the java.util.concurrent package - chances are there's something which will meet your needs.
IMHO, avoid using such logic altogether. Instead, perhaps implement some sort of notification system using property change listeners.
As others have said, it's better to just use join in this case. However, I'd like to generalize your question and ask the following:
In general when a thread is waiting for an event that depends on another thread to occur is it better to:
Use a blocking mechanism (i.e. join, conditional variable, etc.) or
Busy spin without sleep or
Busy spin with sleep?
Now let's see what are the implications for each case:
In this case, using a blocking call will effectively take your thread off the CPU and not schedule it again until the expected event occurs. Good for resource utilization (the thread would waste CPU cycles otherwise), but not very efficient if the event may occur very frequently and at small intervals (i.e. a context switch is much more time-consuming than the time it takes for the event to occur). Generally good when the event will occur eventually, but you don't know how soon.
In case two, you are busy spinning, meaning that you are actively using the CPU without performing useful work. This is the opposite of case 1: it is useful when the event is expected to occur very very soon, but otherwise may occupy the CPU unnecessarily.
This case is a sort of trade-off. You are busy spinning, but at the same time allowing other threads to run by giving up the CPU. This is generally employed when you don't want to saturate the CPU, but the event is expected to occur soon and you want to be sure that you will still be there in almost real time to catch it when it occurs.
I would recommend utilizing the wait/notify mechanism that is built into all Java objects (or using the new Lock code in Java 5).
Thread 1 (waiting for Thread2)
while(!thread2.isDone()) {
synchronize(thread2.lockObject) {
thread2.lockObject.wait();
}
}
Thread 2
// finish work, set isDone=true, notify T1
thread2.lockObject.notify();
'lockObject' is just a plain (Object lockObject = new Object()) -- all Java objects support the wait/notify calls.
After that last call to notify(), Thread1 will wake up, hit the top of the while, see that T2 is now done, and continue execution.
You should account for interrupt exceptions and the like, but using wait/notify is hugely helpful for scenarios like this.
If you use your existing code, with or without sleep, you are burning a huge number of cycles doing nothing... and that's never good.
ADDENDUM
I see a lot of comments saying to use join - if the executing thread you are waiting on will complete, then yes, use join. If you have two parallel threads that run at all times (e.g. a producer thread and a consumer) and they don't "complete", they just run in lock-step with each other, then you can use the wait/notify paradigm I provided above.
The second one.
Better though is to use the join() method of a thread to block the current thread until it is complete :).
EDIT:
I just realised that this only addresses the question as it applies to the two examples you gave, not the question in general (how to wait for a boolean value to be changed by another Thread, not necessarily for the other Thread to actually finish).
To answer the question in general I would suggest that rather than using the methods you described, to do something like this I would recommend using the guarding block pattern as described here. This way, the waiting thread doesn't have to keep checking the condition itself and can just wait to be notified of the change. Hope this helps!
Have you considered: anotherThread.join() ? That will cause the current one to be 'parked' without any overhead until the other one terminates.
The second is better than the first, but neither is very good. You should use anotherThread.join() (or anotherThread.join(timeout)).
Neither, use join() instead:
anotherThread.join();
// anotherThread has finished executing.
Why is Thread.stop() so dangerous?
Why is it advisable to use Thread.interrupted() instead?
I know stop is deprecated. What other thing makes it unsafe?
Is there any place where I can use stop method? If so give me an example.
Why is Thread.stop() so dangerous?
The problems are described in detail here: http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Why is it advisable to use Thread.interrupted() instead?
Because Thread.interrupt() lets the target thread of the interrupt respond when it reaches a point when it knows it is safe to do so.
I know stop is deprecated. What other thing makes it unsafe?
See link above.
Is there any place where I can use stop method? If so give me an example.
In theory, if you knew that the thread you were stopping:
didn't ever update data structures shared with other threads,
didn't use wait/notify or higher level synchronization classes, or classes that depended on them,
and possibly a few other things.
For example, I think it would be safe to stop() this thread:
new Thread(new Runnable(){
public void run(){for (long l = 0; l > 0; l++){}}).start();
However, in most cases it is too difficult to do the analysis to figure out if calling stop() will really be safe. For instance, you have to analyse every possible bit of code (including core and 3rd-party libraries) that the thread uses. So that makes it unsafe by default.