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.
Related
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.
Can I start thread in Java without calling start() method or is there any other mechanism to start a thread?
Simple answer: no.
When you check the corresponding java doc, you will find that there are many methods to deal with other aspects of threads; but start() is the only method to well, start execution of code in that different thread.
Of course you can call
someThread.run()
manually; but that will not cause that another OS thread is brought into existence to execute code in parallel.
In case you are asking "more general"; one has to understand that java.lang.Threads are regarded a very "low level" construct nowadays. We now have things like ExecutorService, Atomic variables, concurrent collections. A good starting point to read about those would be here. But is important to understand: even when using an ExecutorService; in the end, when things happen in parallel, there will be some Thread object somewhere; and start() will be called on that object at some point. No level of enclosing abstractions can make that part obsolete.
And just in case you were really asking that "how to avoid calling start()"; then you probably have an XY problem - in that case; please tell us more about the problem you intend to solve by not calling start.
You can use the ExecutorService of the Concurrency API :
Runnable yourThread = new YourThreadClass() ;
ExecutorService executorService = Executors.newSingleThreadExecutor() ;
executorService.execute(yourThread);
execytorService.shutdown();
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.
I have a thread:
class Foo extends Thread
{
boolean active = true;
public void run()
{
while(active)
{
//do stuff
}
}
public void end()
{
active = false;
}
public void hibernate()
{
synchronized(this)
{
wait();
}
}
}
If another thread calls end(), will Foo immediately see that active is now false? Specifically, because active isn't volatile, I'm not sure that it will. I initially created end() as a clever way of avoiding volatile, but now I'm unsure that it will actually do what I intend.
Additionally, if another thread calls hibernate(), which thread will go to sleep? I'm intending Foo to sleep, so if this doesn't do what I intend, an alternative suggestion would be very welcome.
If another thread calls end(), will Foo immediately see that active is now false?
No it won't. Or at least, it won't see it all of the time.
If you want run to always see the new value immediately, there has to be a "comes after" relationship between the thread assigning to the variable and the thread reading it. This can be achieved:
by declaring active volatile,
by putting synchronized blocks around the statements that read and write the variable,
by making the variable an "atomic" type; e.g. AtomicBoolean, or
by using some other appropriate concurrency class; see the java.util.concurrent.* packages.
... a clever way of avoiding volatile ...
Declaring the variable to be volatile is one way of ensuring proper synchronization. It is a fact that proper synchronization imposes a performance overhead. However, proper synchronization is essential for your application to work reliably, and it is NOT "clever" to avoid it.
(Without proper synchronization, your program will probably still work most of the time, and it might even always work on some machines. However, occasionally it won't work, and the actual behavior is likely to depend on what machine you run the program on, what the machine load is, and other things.)
Additionally, if another thread calls hibernate(), which thread will go to sleep?
The thread that makes the call will go to sleep. And it won't wake up unless some other thread does a notify or notifyAll on the same Foo object.
If you simply want the application to go to sleep and wake up a bit later, use Thread.sleep. But beware that using sleep in the wrong way can make your application slow and unresponsive.
Your suspicion is correct: because active isn't volatile, there is no guarantee that run() will ever see the change made on another thread.
Generally speaking, “clever” ways of avoiding volatile are almost always a bad idea. In fact, even volatile is something you should prefer not to resort to. Most of the time it's safer to stick to locks, monitors, or higher-level synchronization mechanisms.
For your second question, the thread that will go to sleep is the one that called hibernate(). That thread will sleep until it is interrupted, it experiences a spurious wakeup, or some other thread calls notify()/notifyAll() on the Foo instance's monitor. It is usually a mistake to call Object#wait() without surrounding it with a loop that checks the condition being waited for.
You also seem to be confused about the idea of a Foo instance “going to sleep”. A Foo instance isn't a Thread (or even a Runnable), and doesn't create its own thread, so the idea of it going to sleep doesn't make a lot of sense. What you are probably trying to achieve is putting the thread calling Foo#run() to sleep.
Regarding your first question of avoiding volatile , you should try using Thread interruption to signal a running thread to stop.
Use interrupt() instance method from another thread to interrupt running thread.
Use isInterrupted() method in your running thread to check for interruption.
while(!this.isInterrupted()){
//do your work here.
}
Not sure why you want to extend Thread class. If you implements Runnable in that case you should use interrupted in your run method to check for interruption . Please read javadocs to know about some caveats of this method.
This question already has answers here:
How to stop uninterruptible threads in Java
(6 answers)
Closed 9 years ago.
It is a widely known fact that one shall not stop running processes using Thread.stop().
Usually the manuals and tutorials suggest using Thread.interrupt() or some boolean variable instead, and checking from inside the code for that interrupt or variable.
But if I have a library method which takes a very long time to execute sometimes, and I want to give user an ability to stop that process? And library does not give me a mechanisms to do it (does not check thread interrupted status, and no "stop!" variables)?
And, to add to the bad things, there is either no source code for library, or it is just too big to edit it and add checks at appropriate places.
It seems that Thread.stop() is the only solution here. Or maybe there is some workaround?
Why you do not try to use sleep(long timeout) when are waiting for some condition and if had not success, you simple "return" from the thread?
Probably your thread is running in a while (booleanVariable) { },
if it is, you could set this variable as volatile, and the thread controller set it as false.
Think of the Thread.stop() like the System.exit(value), it works, but when you have some bug making you thread stop/vm exit, will be much more harder to find it out.
If practical in your situation, spawn another process and treat that as the unit of work, rather than a thread. Process killing is much more deterministic, though devoting a process to what used to be a thread's work might be too heavyweight for your situation.
The only solution better than using Thread.stop() is to use the library in a seperate thread which you can kill to stop it.
You may want to look for different handles of the function you are running, for example if its IO you can try to close any open connections/streams. If you are stuck with this library (IE can't find one that has better interruption mechanics) Thread.stop() is your only way of stopping the thread.
Thread.stop() is deprecated from java 4 onwards..I read an article to stop a thread by wrapping the call to the library in an separate class that implements InterruptibleChannel which is part of java.nio.
Interruptibleclasses has close() method, through which another thread can call it asynchronously.