Terminate a Thread in Java - java

first: sorry for the nooby question!
consider a normal basic Java programm:
public class TestClass {
public static void main(String[] args) {
Thread t=new Thread()
{
public boolean isRunning;
public void run()
{
while(isRunning);
}
}
t.isRunning=true;
t.start();
t=null;
}
}
The Thread would run for ever doesnt he?
How would I stop the Thread when I accidently set it to null like in the code above? Or what happens if for some reason the Thread object gets nullified?
Basically how does the programm behave? Can I query somehow a running thread without any reference to it and the i just yould stop() it somehow?
Now what about when the Thread object also holds some Data that is needed and will be used in the run method? Are they null or can they still be accessed?
If so it is really essential to get the reference of the object back again even more
edit: I added an android tag to the question. I am more thinking of Android enviroments. The process of an app can be killed very easy and things can go so wrong that a thread gets nullified but its execution is still going on, so getting the reference of a thread back again is important. Like when an activity is killed by the system its reference to a thread is also gone. So before a memory leak occurs there must be sth i can do to prevent from having an ongoing thread before starting another one

That is the case of thread-leak. If you keep on doing that (i.e. starting a thread and forgetting about it) very soon you will get java.lang.OutOfMemoryError: Unable to create new native thread exception.
You should always use a controlled threadpool (like a ExecutorService) and shut it down in the finally clause or register a shutdown hook using Runtime.getRuntime().addShutdownHook to close the threadpool/thread

Related

Thread doesn't seem to exit cleanly - thread hang

So I was trying to do some testing based off some things I know about the Java Memory Model (JMM) because I wanted to see how they applied to a initialization+assignment in a try-catch block with an exception thrown, and I obtained the results I wanted (not related, but I wanted to know if in a try-catch if the allocation could happen before the initialization, and in turn before some exception was thrown, could some other Thread see the uninitialized Object before the Exception was thrown - the answer seems to be no), however I encountered something odd related to my Thread running.
Basically, my Thread never seems to exit. I ran my code to completion in a debugger, and I can see the two Threads running. My main Thread being Thread, and the Thread I created Thread-1. After I complete the main method, my main Thread goes away and is replaced with DestroyJavaVM, as expected. However, Thread-1 seems to be waiting on something.
The part that really confuses me, other than the code being too simple to screw up, is that if I put a
System.out.print("");
inside of the while block, then the slow down caused by I/O seems to cause the Thread to "catch-up" on whatever it was doing, and see the interrupt. Another thing I noticed, is that if I put a breakpoint on the "finished" #println() statement, that the Thread will break on that line, and allow me to continue which causes the print statement in the standard-out, and the program exits. That doesn't make a lot of sense to me. What is happening behind the scenes that causes the created Thread not see the interrupt?
Here is the code I have for my testing, with the unimportant bits removed that were related to me testing the JMM:
public class Foo{
static Foo p;
public static void main(String [] args){
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
}
System.out.println("finished");
}
});
t.start();
for(int i = 0; i < 100000; i++){
try{
p = new Foo();
}catch(Exception pse){
}
}
t.interrupt();
System.out.println("main-method-completed");
}
}
You have probably reproduced the bug JDK-6772683 : Thread.isInterrupted() fails to return true on multiprocessor PC.
As long as the thread runs its while-loop it won't get any messages from other threads in the system. If you do, for instance, Thread.sleep(1); the thread is paused, and a context switch to something else occurs. When the thread is restored, it will get the interrupt notification from some the main loop thread.
If you want to stop the loop in the thread you could either use a volatile variable (these are written and read explcitly from shared memory and are quite expensive), or use, for instance, an java.util.conncurrent.atomic.AtomicBoolean, which at least in theory could use some less expensive method for communicate the its state between threads.

Java force stop a thread from executing inside a loop cycle

I am working on an application using HtmlUnit. As most of the people whom have worked with HtmlUnit knows, that when you have Javascript enabled, it takes a while to load a single page.
My application contains the option to stop the page load, like completely stop all loading and actions.
So I have the Executer class:
public class Executer extends Thread {
private Application app;
public Executer(Application app) {
this.app = app;
}
#Override
public void run() {
for (;;)
while (app.isRunning()) {
app.execute();
}
}
}
Basically this is my executer thread, it calls app.execute() every cycle.
So the execute method, processes a lot of HtmlUnit orders, such as getPage() so htmlunit loads the new page etc.
If the user clicks on Stop button, and then the stop button changes the boolean to false of isRunning, the thread obviously won't stop from executing inside the execute() method because it wasn't done executing yet.
I need to find out a way on how to force the thread from executing ANYTHING.
A solution I found was using executer.stop() it basically stopped everything that the thread is executing, however .stop is deprecated I heard because it just stops everything and some objects may be locked and cause issues.
What solution can I use for this case?
Basically you can't. And there is reason for that - There is no way for java to ensure that application state won't be corrupted if thread is terminated on any instruction it is executing.
For example:
try(InputStream in = openStream()){
readStreamContent(in);
}
If java would terminate thread during execution of readStreamContent() the stream would never be closed.
Another example:
mutex.acquire();
try {
doSomething();
} finally {
mutex.release();
}
If we would terminate thread while in doSomething() it would never release mutex. This may leave many threads hanging on mutex that would never be released.
If you do not want to use Thread.Stop(), than you MUST implement special code in your execute()-Method which also checks the app.isRunning()-State.
I am afraid there is no other way to stop the execute()-Method.
EDIT:
As mentioned here, the use of thread.stop(); should be used with care!
Just set the isInterrupted flag of the Executor instance to true by calling
executor.interrupt()
This is the safest way to stop a Thread. when you load a page the thread does not wait actively therefore if it is interrupted while waiting for the server to responde, the executor will stop
practically right away. Your Application.isRunning() is not necessary either as isInterrupted flag does exactly the same.
EDIT:
Dont ever use Thread.stop() to stop a thread. Its behavior may become unpredictable and in the future
very difficult to debug if certain unexpected behaviors occur.

isAlive() method of java thread is not working properly?

I was trying a example of isAlive() method of java threading. But i found that isAlive() method is returning false even if thread has been already started. Can someone please tell me what am i doing wrong? Here is the code snippet.
package app;
public class ThreadAliveDemo {
public static void main(String[] args) {
Thread myThread;
myThread = new Thread()
{
public void run()
{
Thread.sleep(3000);
System.out.println("My Thread.");
}
};
myThread.setName("My Thread");
myThread.start();
if(!myThread.isAlive())
{
myThread.setName("My Thread");
myThread.start();
}
}
}
There's a good chance the thread will have started, executed, and finished, between your call to start() and your call to isAlive().
Java offers no guarantees on the sequence in which these things happen. It could execute the spawned thread immediately, or it may choose to defer it until a bit later.
Incidentally, your code is trying to re-start the thread after it has died. This is not permitted:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
So calling start() after checking isAlive() is never going to work.
If my memory serves me well java has quite long periods between thread switching so it is possible that the isAlive fails because the thread is not yet alive. Try to add some waiting time between thread.start() and thread.isAlive()
I haven't done any multithreading in java yet, but it looks to me like your thread probably will have run and exited before the isAlive() check. After all, looks like your thread just prints something out and then dies.
Happened to me recently, fixed it using
if(yourThread.getState() == Thread.State.NEW){
yourThread.start();
}
instead of yourThread.isAlive();
I don't see the point of the code you have posted. Thread.start() starts the thread: you don't need to start it twice. I don't see how your code can realistically into a situation where it has a Thread and doesn't know whether it has been started or not; anyway there are plenty of ways to code around that so it can't happen.

Is it legal to call the start method twice on the same Thread?

The following code leads to java.lang.IllegalThreadStateException: Thread already started when I called start() method second time in program.
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
This happens the second time updateUI.start() is called. I've stepped through it multiple times and the thread is called and completly runs to completion before hitting updateUI.start().
Calling updateUI.run() avoids the error but causes the thread to run in the UI thread (the calling thread, as mentioned in other posts on SO), which is not what I want.
Can a Thread be started only once? If so than what do I do if I want to run the thread again? This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
From the Java API Specification for the Thread.start method:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
Furthermore:
Throws:
IllegalThreadStateException - if the thread was already started.
So yes, a Thread can only be started once.
If so than what do I do if I want to
run the thread again?
If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Exactly right. From the documentation:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
In terms of what you can do for repeated computation, it seems as if you could use SwingUtilities invokeLater method. You are already experimenting with calling run() directly, meaning you're already thinking about using a Runnable rather than a raw Thread. Try using the invokeLater method on just the Runnable task and see if that fits your mental pattern a little better.
Here is the example from the documentation:
Runnable doHelloWorld = new Runnable() {
public void run() {
// Put your UI update computations in here.
// BTW - remember to restrict Swing calls to the AWT Event thread.
System.out.println("Hello World on " + Thread.currentThread());
}
};
SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");
If you replace that println call with your computation, it might just be exactly what you need.
EDIT: following up on the comment, I hadn't noticed the Android tag in the original post. The equivalent to invokeLater in the Android work is Handler.post(Runnable). From its javadoc:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* #param r The Runnable that will be executed.
*
* #return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
So, in the Android world, you can use the same example as above, replacing the Swingutilities.invokeLater with the appropriate post to a Handler.
No, we cannot start Thread again, doing so will throw runtimeException java.lang.IllegalThreadStateException.
>
The reason is once run() method is executed by Thread, it goes into dead state.
Let’s take an example-
Thinking of starting thread again and calling start() method on it (which internally is going to call run() method) for us is some what like asking dead man to wake up and run. As, after completing his life person goes to dead state.
public class MyClass implements Runnable{
#Override
public void run() {
System.out.println("in run() method, method completed.");
}
public static void main(String[] args) {
MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
thread1.start();
thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
}
}
/*OUTPUT in run() method, method completed. Exception in thread
"main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
*/
check this
The just-arrived answer covers why you shouldn't do what you're doing. Here are some options for solving your actual problem.
This particular thread is doing some
calculation in the background, if I
don't do it in the thread than it's
done in the UI thread and the user has
an unreasonably long wait.
Dump your own thread and use AsyncTask.
Or create a fresh thread when you need it.
Or set up your thread to operate off of a work queue (e.g., LinkedBlockingQueue) rather than restarting the thread.
What you should do is create a Runnable and wrap it with a new Thread each time you want to run the Runnable.
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
It is as you said, a thread cannot be started more than once.
Straight from the horse's mouth: Java API Spec
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
If you need to re-run whatever is going on in your thread, you will have to create a new thread and run that.
To re-use a thread is illegal action in Java API.
However, you could wrap it into a runnable implement and re-run that instance again.
Yes we can't start already running thread.
It will throw IllegalThreadStateException at runtime - if the thread was already started.
What if you really need to Start thread:
Option 1 ) If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Can a Thread be started only once?
Yes. You can start it exactly once.
If so than what do I do if I want to run the thread again?This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
Don't run the Thread again. Instead create Runnable and post it on Handler of HandlerThread. You can submit multiple Runnable objects. If want to send data back to UI Thread, with-in your Runnable run() method, post a Message on Handler of UI Thread and process handleMessage
Refer to this post for example code:
Android: Toast in a thread
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
I have had to fix a resource leak that was caused by a programmer who created a Thread but instead of start()ing it, he called the run()-method directly. So avoid it, unless you really really know what side effects it causes.
I don't know if it is good practice but when I let run() be called inside the run() method it throws no error and actually does exactly what I wanted.
I know it is not starting a thread again, but maybe this comes in handy for you.
public void run() {
LifeCycleComponent lifeCycleComponent = new LifeCycleComponent();
try {
NetworkState firstState = lifeCycleComponent.getCurrentNetworkState();
Thread.sleep(5000);
if (firstState != lifeCycleComponent.getCurrentNetworkState()) {
System.out.println("{There was a NetworkState change!}");
run();
} else {
run();
}
} catch (SocketException | InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread checkingNetworkStates = new Thread(new LifeCycleComponent());
checkingNetworkStates.start();
}
Hope this helps, even if it is just a little.
Cheers

How to abort a thread in a fast and clean way in java?

Here is my problem: I've got a dialog with some parameters that the user can change (via a spinner for example). Each time one of these parameters is changed, I launch a thread to update a 3D view according to the new parameter value.
If the user changes another value (or the same value again by clicking many times on the spinner arrow) while the first thread is working, I would like to abort the first thread (and the update of the 3D view) and launch a new one with the latest parameter value.
How can I do something like that?
PS: There is no loop in the run() method of my thread, so checking for a flag is not an option: the thread updating the 3D view basically only calls a single method that is very long to execute. I can't add any flag in this method asking to abort either as I do not have access to its code.
Try interrupt() as some have said to see if it makes any difference to your thread. If not, try destroying or closing a resource that will make the thread stop. That has a chance of being a little better than trying to throw Thread.stop() at it.
If performance is tolerable, you might view each 3D update as a discrete non-interruptible event and just let it run through to conclusion, checking afterward if there's a new latest update to perform. This might make the GUI a little choppy to users, as they would be able to make five changes, then see the graphical results from how things were five changes ago, then see the result of their latest change. But depending on how long this process is, it might be tolerable, and it would avoid having to kill the thread. Design might look like this:
boolean stopFlag = false;
Object[] latestArgs = null;
public void run() {
while (!stopFlag) {
if (latestArgs != null) {
Object[] args = latestArgs;
latestArgs = null;
perform3dUpdate(args);
} else {
Thread.sleep(500);
}
}
}
public void endThread() {
stopFlag = true;
}
public void updateSettings(Object[] args) {
latestArgs = args;
}
The thread that is updating the 3D view should periodically check some flag (use a volatile boolean) to see if it should terminate. When you want to abort the thread, just set the flag. When the thread next checks the flag, it should simply break out of whatever loop it is using to update the view and return from its run method.
If you truly cannot access the code the Thread is running to have it check a flag, then there is no safe way to stop the Thread. Does this Thread ever terminate normally before your application completes? If so, what causes it to stop?
If it runs for some long period of time, and you simply must end it, you can consider using the deprecated Thread.stop() method. However, it was deprecated for a good reason. If that Thread is stopped while in the middle of some operation that leaves something in an inconsistent state or some resource not cleaned up properly, then you could be in trouble. Here's a note from the documentation:
This method is inherently unsafe.
Stopping a thread with Thread.stop
causes it to unlock all of the
monitors that it has locked (as a
natural consequence of the unchecked
ThreadDeath exception propagating up
the stack). If any of the objects
previously protected by these monitors
were in an inconsistent state, the
damaged objects become visible to
other threads, potentially resulting
in arbitrary behavior. Many uses of
stop should be replaced by code that
simply modifies some variable to
indicate that the target thread should
stop running. The target thread should
check this variable regularly, and
return from its run method in an
orderly fashion if the variable
indicates that it is to stop running.
If the target thread waits for long
periods (on a condition variable, for
example), the interrupt method should
be used to interrupt the wait. For
more information, see Why are
Thread.stop, Thread.suspend and
Thread.resume Deprecated?
Instead of rolling your own boolean flag, why not just use the thread interrupt mechanism already in Java threads? Depending on how the internals were implemented in the code you can't change, you may be able to abort part of its execution too.
Outer Thread:
if(oldThread.isRunning())
{
oldThread.interrupt();
// Be careful if you're doing this in response to a user
// action on the Event Thread
// Blocking the Event Dispatch Thread in Java is BAD BAD BAD
oldThread.join();
}
oldThread = new Thread(someRunnable);
oldThread.start();
Inner Runnable/Thread:
public void run()
{
// If this is all you're doing, interrupts and boolean flags may not work
callExternalMethod(args);
}
public void run()
{
while(!Thread.currentThread().isInterrupted)
{
// If you have multiple steps in here, check interrupted peridically and
// abort the while loop cleanly
}
}
Isn't this a little like asking "How can I abort a thread when no method other than Thread.stop() is available?"
Obviously, the only valid answer is Thread.stop(). Its ugly, could break things in some circumstances, can lead to memory/resource leaks, and is frowned upon by TLEJD (The League of Extraordinary Java Developers), however it can still be useful in a few cases like this. There really isn't any other method if the third party code doesn't have some close method available to it.
OTOH, sometimes there are backdoor close methods. Ie, closing an underlying stream that its working with, or some other resource that it needs to do its job. This is seldom better than just calling Thread.stop() and letting it experience a ThreadDeathException, however.
The accepted answer to this question allows you to submit batch work into a background thread. This might be a better pattern for that:
public abstract class dispatcher<T> extends Thread {
protected abstract void processItem(T work);
private List<T> workItems = new ArrayList<T>();
private boolean stopping = false;
public void submit(T work) {
synchronized(workItems) {
workItems.add(work);
workItems.notify();
}
}
public void exit() {
stopping = true;
synchronized(workItems) {
workItems.notifyAll();
}
this.join();
}
public void run() {
while(!stopping) {
T work;
synchronized(workItems) {
if (workItems.empty()) {
workItems.wait();
continue;
}
work = workItems.remove(0);
}
this.processItem(work);
}
}
}
To use this class, extend it, providing a type for T and an implementation of processItem(). Then just construct one and call start() on it.
You might consider adding an abortPending method:
public void abortPending() {
synchronized(workItems) {
workItems.clear();
}
}
for those cases where the user has skipped ahead of the rendering engine and you want to throw away the work that has been scheduled so far.
A thread will exit once it's run() method is complete, so you need some check which will make it finish the method.
You can interrupt the thread, and then have some check which would periodically check isInterrupted() and return out of the run() method.
You could also use a boolean which gets periodically checked within the thread, and makes it return if so, or put the thread inside a loop if it's doing some repetative task and it will then exit the run() method when you set the boolean. For example,
static boolean shouldExit = false;
Thread t = new Thread(new Runnable() {
public void run() {
while (!shouldExit) {
// do stuff
}
}
}).start();
Unfortunately killing a thread is inherently unsafe due to the possibilities of using resources that can be synchronized by locks and if the thread you kill currently has a lock could result in the program going into deadlock (constant attempt to grab a resource that cannot be obtained). You will have to manually check if it needs to be killed from the thread that you want to stop. Volatile will ensure checking the variable's true value rather than something that may have been stored previously. On a side note Thread.join on the exiting thread to ensure you wait until the dying thread is actually gone before you do anything rather than checking all the time.
You appear to not have any control over the thread that is rendering the screen but you do appear to have control of the spinner component. I would disable the spinner while the thread is rendering the screen. This way the user at least has some feedback relating to their actions.
I suggest that you just prevent multiple Threads by using wait and notify so that if the user changes the value many times it will only run the Thread once. If the users changes the value 10 times it will fire off the Thread at the first change and then any changes made before the Thread is done all get "rolled up" into one notification. That won't stop a Thread but there are no good ways to do that based on your description.
The solutions that purpose the usage of a boolean field are the right direction. But the field must be volatile.
The Java Language Spec says:
"For example, in the following (broken) code fragment, assume that this.done is a non-
volatile boolean field:
while (!this.done)
Thread.sleep(1000);
The compiler is free to read the field this.done just once, and reuse the cached value in each execution of the loop. This would mean that the loop would never terminate, even if another thread changed the value of this.done."
As far as I remember "Java Concurrency in Pratice" purposes to use the interrupt() and interrupted() methods of java.lang.Thread.
The way I have implemented something like this in the past is to implement a shutdown() method in my Runnable subclass which sets an instance variable called should_shutdown to true. The run() method normally does something in a loop, and will periodically check should_shutdown and when it is true, returns, or calls do_shutdown() and then returns.
You should keep a reference to the current worker thread handy, and when the user changes a value, call shutdown() on the current thread, and wait for it to shutdown. Then you can launch a new thread.
I would not recommend using Thread.stop as it was deprecated last time I checked.
Edit:
Read your comment about how your worker thread just calls another method which takes a while to run, so the above does not apply. In this case, your only real options are to try calling interrupt() and see if has any effect. If not, consider somehow manually causing the function your worker thread is calling to break. For example, it sounds like it is doing some complex rendering, so maybe destroy the canvas and cause it to throw an exception. This is not a nice solution, but as far as I can tell, this is the only way to stop a thread in suituations like this.
Since you're dealing with code you don't have access to you're probably out of luck. The standard procedure (as outlined in the other answers) is to have a flag that is checked periodically by the running thread. If the flag is set, do cleanup and exit.
Since that option is not available to you, the only other option is to force quit the running process. This used to be possible by calling Thread.stop(), but that method has been permanently deprecated for the following reason (copied from the javadocs):
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
More info on this topic can be found here.
One absolute sure way you could accomplish your request (although this is not a very efficient way to do this) is to start a new java process via Runtime.exec() and then stopping that process as necessary via Process.destroy(). Sharing state between processes like this is not exactly trivial, however.
Instead of playing with thread starting and stopping, have you considered having the thread observe the properties that you're changing through your interface? You will at some point still want a stop condition for your thread, but this can be done this was as well. If you're a fan of MVC, this fits nicely into that sort of design
Sorry, after re-reading your question, neither this nor any of the other 'check variable' suggestions will solve your problem.
The correct answer is to not use a thread.
You should be using Executors, see the package: java.util.concurrent
Maybe this can help you: How can we kill a running thread in Java?
You can kill a particular thread by setting an external class variable.
Class Outer
{
public static flag=true;
Outer()
{
new Test().start();
}
class Test extends Thread
{
public void run()
{
while(Outer.flag)
{
//do your work here
}
}
}
}
if you want to stop the above thread, set flag variable to false. The other way to kill a thread is just registering it in ThreadGroup, then call destroy(). This way can also be used to kill similar threads by creating them as group or register with group.

Categories

Resources