End execution of Thread without using its stop() method - java

I have a Swing form with a button, which is when clicked starts SocketServer for listening to incoming requests in a separate thread. Following is structure of classes I have.
MainForm : This is my main class which launches Swing Form. It has two buttons, "start server" and "stop buttons".
MySocketServer : This class is where SocketServer object exists, it has methods startServer() and stopServer().
Following is Start button's Click Event Body.
t = new Thread(new Runnable() //Object t is created globally in this main class.
{
public void run()
{
myss = new MySocketServer(); //Object myss has similar accessibility as t.
myss.startServer();
}
});
t.start();
And Following is Stop Button's Click Event Body
myss.stopServer();
if(t.isAlive());
System.out.println("Thread is still alive!!");
Though I can toggle SockeServer "start" and "stop" as my times I want, but I realize that everytime I start the server, new thread gets created and it remains active even though server is stopped using MySocketServer's method.
I can use stop() of Thread and stop the thread execution but since it is depreciated and I have studied that threads get ended once their run() method has executed completely, but I have startServer() method separated so that it can handle connected clients separately.
Please note that startServer() has While-Listen loop, so essentially run() method of thread is in infinite state of execution, until I explicitly call stopServer() and halt the loop.
what can be done here?

Firstly, you are right to not try to use Thread.stop(). It is potentially dangerous.
So what should you do?
One possibility might to be to write your server thread like this:
....
ServerSocket ss = new ServerSocket(...);
try {
while (keepGoing) {
Socket s = ss.accept(...);
try {
// do stuff
} finally {
// close socket
}
}
} finally {
// close the server socket
}
and have stopServer clear the keepGoing flag. But the problem is that the stop typically will come while the thread is blocked in the accept call, and there's nothing to unblock it.
Another possibility might be to call Thread.interrupt() on the thread. That causes some things to unblock, and throw an exception, but I don't think it will unblock the accept() call though. (However, this is still better than setting a flag if the "do stuff" part needs interrupting.)
The real solution (I think) is to close the ServerSocket. This will cause the ss.accept() call to unblock and throw an exception, which you need to handle in the server thread.

In your MySocketServer class in the while loop you need a flag which will test if it should keep running or not.
In your newly added shutdown method set the flag which the loop in the thread will test. Once the loop breaks and run() returns the thread will end.

You shouldn't use stop(). Take a look at this http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
The solution with infinite loop and start/stop flags is straightforward but leads to ineffective using of CPU time. The better way is to use wait/notify approach. The way you operate with MySocketServer gives me feeling that you have other infinite loop inside the startServer(). That's why you have to stop it. It would be better to wrap this loop into it's own thread internally and make start/stop methods operate with this thread state in wait/notify manner.
Forgot to mention, as your GUI runs in its own thread you can't escape start/stop flag inside the MySocketServer because using wait() in GUI thread will make it hanged.

Related

Java multithreading error [duplicate]

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

Shut down a single thread running

Suppose during my running I would like to shutdown a single thread gracefully!
I don't want to use Thread.stop() nor Thread.destroy() due to their unsafe behavior.
Note: I'm familiar with using ExecutorService.shutdown() option.
But I would like to know the other way to implement.
The standard way to stop a thread is to call thread.interrupt();. To make it work, you need to make sure you thread responds to interruption, for example:
Thread t = new Thread(new Runnable() { public void run {
while(!Thread.currentThread().isInterrupted()) {
//your code here
}
}});
t.start();
t.interrupt();
This only works if the condition is checked regularly. Note that you can delegate the interruption mechanism to interruptible methods (typically I/O, blocking queues, sleep/wait provide methods that can block until they are interrupted).
Note: In this example, you can also use:
while(!interrupted()) {
//your code here
}
interrupted() does the same thing as Thread.currentThread().isInterrupted() except that the interrupted flag is reset. Since it is your thread, it does not matter.
You could have isStopped()flag in your code. And the running thread should regularly check this flag to see if it should stop. Note that stopping a thread gracefully requires the running code to be written in a way that allows stopping.
You can take a look at this question for some more detailed answers
You have to make the run() method of the thread terminate for some reason. How you achieve this depends on what the thread does.
If the thread is looping, you can stop it by raising a flag (checked by the condition of the loop).
If the thread is waiting over a Socket or any other stream, just close the stream.
If the thread is blocked on a call that can throw an InterruptedException, you can interrupt() the thread and ignore the exception.
If the thread is consuming the elements of a blocking queue, use the poison pill method, which means putting on the queue an element that just means "stop looping".
If you have a loop inside your run() method of your Thread then one option would be that your loop checks for the value of a flag on every iteration.
You can set the flag from outside the code, such as your thread would stop executing before starting the next iteration.

destroy java thread

help me kill java thread
So I have code:
new Thread(new Runnable() {
public void run() {
// process() method is time-consuming and has no while-loop in his body
// so I want to give user to stop it
new AnyObject().process();
}
}).start();
My question is how can I kill such thread?
You can call Thread.stop() however you should understand what it does as its deprecated for a reason (being that it can leave your system in an inconsistent state) If the work you are doing is self contained and well behaved, it won't be a problem.
However if it were well behaved you wouldn't need to stop it this way, thus the catch-22 with this "solution" ;)
Ultimately the only safe way to stop a thread is to have it exit its run loop. There are two main ways to do that, set a flag that the AnyObject.process method checks periodically or have the AnyObject.process method respond correctly to an interrupt and exit. However to use the latter method, you will need to keep a reference to the thread around so you can issue the interrupt method on it.
You should probably keep a reference to your AnyObject as well in case you need to reference it later.
If all that fails, System.exit() will usually do the trick.
You can call interrupt() on thread in order to stop it.
you can use thread.interrupt() to stop thread!
Your Thread will be terminated when the run() method will be terminated.
In your example, it will be when the new AnyObject().process(); will be terminated.
So, terminate the process() method will terminate your Thread.

How to avoid use of Thread.Sleep

I never gave the use of Thread.Sleep much thought, until I downloaded the latest version of Netbeans. Netbeans now warns you not to use Thread.Sleep. So I did some research on the topic and found people stating that you only need to use Thread.Sleep for debugging/testing purposes and that if you use it at any other time you have poorly written code.
So my question is how can I keep from using Thread.Sleep in the following situation.
I have written a server application that interfaces with another application. The server has two threads:
Handles the data coming over the socket and sends back other information or just plain acknoledgements.
This is the main thread. After kicking off the socket thread it going into an indefinite while loop. Within this while loop I check to make sure the socket thread is still active and that the user hasn't asked to exit the application via a TrayIcon interface. Then I sleep and continue this while loop.
With this application, the TrayIcon is the only UI.
Here is the snippet I'm referencing:
// continues running as long as the exitth file is not present and
// the tray icon is not in a safe to exit status.
while(doNotExit())
{
if (getPrimaryThread() == null || !getPrimaryThread().isAlive())
resetsThreadAndSocket();
try
{
// check to see if the socket threads are still active, if not create new ones.
if ((getPrimaryThread() == null || !getPrimaryThread().isAlive()))
createSocketThread();
// check right before sleeping that the user does not want to exit.
if(getTrayIcon().isExiting())
break;
// puts the main Thread to sleep for 3 seconds
Thread.sleep(3000);
}
catch(SQLException ex)
{
_log.error(ex.getMessage(), ex);
restartDatabase();
}
}
The 'preferred' method in most cases would be to use the ScheduledExecutorService built into JavaSE for performing a periodic task, rather than reimplementing it yourself every time using a while loop and Thread.Sleep().
There's nothing wrong per-se with your example. The language just now has a much more robust support for doing that built into it as of Java 5.
Instead of your Thread.sleep(3000) do:
getPrimaryThread().join(3000)
This will wait for the thread to exit for 3 seconds.
You should consider attaching an event listener to your tray icon instead of polling its state. That way you won't need an extra thread just for monitoring.
If you can't do that for some reason, you can still do away with the extra thread as the Timer class can do the waiting for you.
You seem to be paranoid that some condition (maybe a RuntimeException or Error?) is going to cause your socket Thread to just die. Ideally, you would design your Socket Thread such that it protected itself from crashing. The following example creates a loop that can only be broken as a result of a JVM Error or Thread interrupt:
public void run() {
while(!Thread.currentThread.isInterrupted()) {
try {
//you application logic
} catch (RuntimeException e) {
//log uncaught exception
}
}
}
In order to shutdown the application, you would attach a listener to the TrayIcon which contained a reference to the SocketThread and could stop it by simply interrupting it.
socketThread.interrupt();
I'll leave figuring how to add an ActionListener to a TrayIcon up to you.

How to start/stop/restart a thread in Java?

I am having a real hard time finding a way to start, stop, and restart a thread in Java.
Specifically, I have a class Task (currently implements Runnable) in a file Task.java. My main application needs to be able to START this task on a thread, STOP (kill) the thread when it needs to, and sometimes KILL & RESTART the thread...
My first attempt was with ExecutorService but I can't seem to find a way for it restart a task. When I use .shutdownnow() any future call to .execute() fails because the ExecutorService is "shutdown"...
So, how could I accomplish this?
Once a thread stops you cannot restart it. However, there is nothing stopping you from creating and starting a new thread.
Option 1: Create a new thread rather than trying to restart.
Option 2: Instead of letting the thread stop, have it wait and then when it receives notification you can allow it to do work again. This way the thread never stops and will never need to be restarted.
Edit based on comment:
To "kill" the thread you can do something like the following.
yourThread.setIsTerminating(true); // tell the thread to stop
yourThread.join(); // wait for the thread to stop
Review java.lang.Thread.
To start or restart (once a thread is stopped, you can't restart that same thread, but it doesn't matter; just create a new Thread instance):
// Create your Runnable instance
Task task = new Task(...);
// Start a thread and run your Runnable
Thread t = new Thread(task);
To stop it, have a method on your Task instance that sets a flag to tell the run method to exit; returning from run exits the thread. If your calling code needs to know the thread really has stopped before it returns, you can use join:
// Tell Task to stop
task.setStopFlag(true);
// Wait for it to do so
t.join();
Regarding restarting: Even though a Thread can't be restarted, you can reuse your Runnable instance with a new thread if it has state and such you want to keep; that comes to the same thing. Just make sure your Runnable is designed to allow multiple calls to run.
It is impossible to terminate a thread unless the code running in that thread checks for and allows termination.
You said: "Sadly I must kill/restart it ... I don't have complete control over the contents of the thread and for my situation it requires a restart"
If the contents of the thread does not allow for termination of its exectuion then you can not terminate that thread.
In your post you said: "My first attempt was with ExecutorService but I can't seem to find a way for it restart a task. When I use .shutdownnow()..."
If you look at the source of "shutdownnow" it just runs through and interrupts the currently running threads. This will not stop their execution unless the code in those threads checks to see if it has been ineterrupted and, if so, stops execution itself. So shutdownnow is probably not doing what you think.
Let me illustrate what I mean when I say that the contents of the thread must allow for that thread to be terminated:
myExecutor.execute(new Runnable() {
public void run() {
while (true) {
System.out.println("running");
}
}
});
myExecutor.shutdownnow();
That thread will continue to run forever, even though shutdownnow was called, because it never checks to see if it has been terminated or not. This thread, however, will shut down:
myExecutor.execute(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
System.out.println("running");
}
}
});
myExecutor.shutdownnow();
Since this thread checks to see whether or not it has been interrupted / shut down / terminated.
So if you want a thread that you can shut down, you need to make sure it checks to see if it has been interrupted. If you want a thread that you can "shut down" and "restart" you can make a runnable that can take new tasks as was mentioned before.
Why can you not shut down a running thread? Well I actually lied, you can call "yourThread.stop()" but why is this a bad idea? The thread could be in a synchronized (or other critical section, but we will limit ourselves to setions guarded by the syncrhonized key word here) section of code when you stop it. synch blocks are supposed to be executed in their entirity and only by one thread before being accessed by some other thread. If you stop a thread in the middle of a synch block, the protection put into place by the synch block is invalidated and your program will get into an unknown state. Developers make put stuff in synch blocks to keep things in synch, if you use threadInstance.stop() you destroy the meaning of synchronize, what the developer of that code was trying to accomplish and how the developer of that code expected his synchronized blocks to behave.
You can't restart a thread so your best option is to save the current state of the object at the time the thread was stopped and when operations need to continue on that object you can recreate that object using the saved and then start the new thread.
These two articles Swing Worker and Concurrency may help you determine the best solution for your problem.
As stated by Taylor L, you can't just "stop" a thread (by calling a simple method) due to the fact that it could leave your system in an unstable state as the external calling thread may not know what is going on inside your thread.
With this said, the best way to "stop" a thread is to have the thread keep an eye on itself and to have it know and understand when it should stop.
If your task is performing some kind of action in a loop there is a way to pause/restart processing, but I think it would have to be outside what the Thread API currently offers. If its a single shot process I am not aware of any way to suspend/restart without running into API that has been deprecated or is no longer allowed.
As for looped processes, the easiest way I could think of is that the code that spawns the Task instantiates a ReentrantLock and passes it to the task, as well as keeping a reference itself. Every time the Task enters its loop it attempts a lock on the ReentrantLock instance and when the loop completes it should unlock. You may want to encapsulate all this try/finally, making sure you let go of the lock at the end of the loop, even if an exception is thrown.
If you want to pause the task simply attempt a lock from the main code (since you kept a reference handy). What this will do is wait for the loop to complete and not let it start another iteration (since the main thread is holding a lock). To restart the thread simply unlock from the main code, this will allow the task to resume its loops.
To permanently stop the thread I would use the normal API or leave a flag in the Task and a setter for the flag (something like stopImmediately). When the loop encountered a true value for this flag it stops processing and completes the run method.
Sometimes if a Thread was started and it loaded a downside dynamic class which is processing with lots of Thread/currentThread sleep while ignoring interrupted Exception catch(es), one interrupt might not be enough to completely exit execution.
In that case, we can supply these loop-based interrupts:
while(th.isAlive()){
log.trace("Still processing Internally; Sending Interrupt;");
th.interrupt();
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
There's a difference between pausing a thread and stopping/killing it. If stopping for you mean killing the thread, then a restart simply means creating a new thread and launching.
There are methods for killing threads from a different thread (e.g., your spawner), but they are unsafe in general. It might be safer if your thread constantly checks some flag to see if it should continue (I assume there is some loop in your thread), and have the external "controller" change the state of that flag.
You can see a little more in:
http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
May I ask why you want to kill the thread and restart it? Why not just have it wait until its services are needed again? Java has synchronization mechanisms exactly for that purpose. The thread will be sleeping until the controller notifies it to continue executing.
You can start a thread like:
Thread thread=new Thread(new Runnable() {
#Override
public void run() {
try {
//Do you task
}catch (Exception ex){
ex.printStackTrace();}
}
});
thread.start();
To stop a Thread:
thread.join();//it will kill you thread
//if you want to know whether your thread is alive or dead you can use
System.out.println("Thread is "+thread.isAlive());
Its advisable to create a new thread rather than restarting it.

Categories