Consider the following case:
main() {
ClassA insA = new ClassA();
insA.run();
}
ClassA.run() {
for(;;) {
RMI.call();
blahblah();
}
}
RMI.call() is an RMI function which blocks the thread using Semaphore.acquire() till something (in another thread) happens.
The question is: How can I safely kill all the threads?
defining a stop() function in ClassA like below:
stop() {
Thread.currentThread.interrupt();
}
and calling it from outside (e.g. main())will NOT interrupt the RMI call thread.
How can I interrupt the original thread, so I can exit the code properly?
Or any other way the exit safely?
Check this library: http://java.net/projects/interruptiblermi.
Thread#interrupt() will not help.
Related
Why do we call the start() method, which in turn calls the run() method?
Can't we directly make a call to run()?
Please give an example where there is a difference.
No, you can't. Calling run will execute run() method in the same thread, without starting new thread.
Why do we call the start() method, which in turn calls the run() method?
No that's imprecise. start() in turn does not call the run method.
instead it starts the thread which executes the run method. This is native.
Can't we directly make a call to run()?
If you call run() directly you don't start the thread, you just execute the method on the same caller method.
Please give an example where there is a difference.
There are millions on the web. Hence I don't duplicate.
Actually thread.start() creates a new thread and have its own execution scenario.
but thread.run() not creating any new thread, instead it execute the run method in the current running thread.
So guys if you are using thread.run() then think that what is the use of multi-threading if you want only one thread execute all run method.
Because start() doesnt just call run(). It starts a new thread and in that thread calls run().
you can't run directly the run() method. Whenever start your thread by using thread.start(), then the run() method has been called and performed the further operation.
Main difference is that when program calls start() method a new Thread is created and code inside run() method is executed in new Thread.If you call run() method directly no new Thread is created and code inside run() will execute on current Thread.
Most of the time calling run() is bug or programming mistake because caller has intention of calling start() to create new thread and this error can be detect by many static code coverage tools like findbugs. If you want to perform time consuming task than always call start() method otherwise your main thread will stuck while performing time consuming task if you call run() method directly. Another difference between start vs run in Java thread is that you can not call start() method twice on thread object. once started, second call of start() will throw IllegalStateException in Java while you can call run() method twice.
If you call run() directly, the code gets executed in the calling thread. By calling start(), a new thread is created other than the main thread and is executed in parallel.
Because start(); is synchronized and run(); is simple/regular method. Same as java knows starting execution from main(); method. As thread knows starting execution from run();
Here is the Source code from Thread Class:
run(); code:
#Override
public void run() { // overriding from Runnable
if (target != null) {
target.run();
}
}
start(); code:
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
In short start(); is the manager of threads, how to manage etc. and run(); is tarting point of thread's working.
this is the work done by start method
synchronized public void start()
{
//it calls start0() method internally and start0() method does below
//create a real child thread and register with thread scheduler
//create runtime stack for child thread
//call run() on underlying Runtime object
}
I have an application in which there are multiple threads. I want them to execute in order.so i choose executorService for multi-threading. if any one of thread(run method) is in error , I want to move on to net thread so that by the end i can come to know how many thread are completed successfully (count needed).My sample code:
The Main class:
public class MySampleClass{
ExecutorService executor = Executors.newSingleThreadExecutor();
for(int i=0; i<=100;i++){
executor.submit(new ThreadClass());
}
//After all threads executed now to shutdown executor
executor.shutdown()
executor.awaitForTermination(1,Time.MILLISECONDS);
My Sample Thread Class :
public class ThreadClass implements Runnable{
#override
public void run(){
boolean isCompleted= doAction();
if(!isCompleted){
// I want here to stop this thread only..what to do ?
//executor.shutdown will stop all other threads
}
}
}
Any Suggestion what to do ?? Am i doing it wrong way ?
Thread.currentThread().interrupt();
You shouldn't stop a thread. There is a reason Thread.stop is deprecated. Instead you can interrupt the current thread.
You can use Callable instead of Runnable. If you do that, submit method returns a Future (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html) instance on which you can verify if the callable do it´s work in the right way. The documentation explains it:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable)
Hope i explained in the right way.
I have a TimerTask that gets started as the first thing in my run() method of my Runnable class. I want to make sure that it gets stopped when the runnable is shutdown.
The runnable is started via an ExecutorService. I don't see a way to get a hook back to the runnable from the ExecutorService when shutdown() is called.
How can I make sure that the TimerTask is stopped?
Thanks
use ExecuterService.submit() to get back Future object once the task is completed.
ExecutorService.Submit()
The method call TimerTask.cancel() should do the desired.
Your Runnable.run method could be designed like this:
public void run() {
pingTask = new PingTimerTask(...);
try {
...
} finally {
/* this code even gets executed when an exception
* (for example an *InterruptedException*) was thrown:
*/
pingTask.cancel();
}
}
I have developed a JSP web application which, on every request, spawns a new Java Thread. In every newly spawned thread I create a Process using Runtime.exec() and store the process object in an instance variable in thread. I have a requirement in which I have to kill the created subprocess and also stop the thread. So, I overrode the interrupt method in the thread and in the overridden method I'm calling destroy() on already stored Process object in the instance variable. Following is the code:
public class MyThread extends Thread {
private Process subprocess;
#Override
public void run() {
subprocess = Runtime.getRuntime().exec("myprocess.exe");
subprocess.waitFor();
/*
Some more statements
*/
}
#Override
public void interrupt() {
if(subprocess!=null) {
System.out.println("Destroying Process");
subprocess.destroy();
}
super.interrupt();
}
}
Is it illeagal to override interrupt method?
Its important that I kill the created process before I interrupt the thread that creates it. I see that the thread does get interrupted because the statements after waitFor() do not get executed. But, however, destroy() doesnt work (but gets called) and the created "myprocess.exe" completes execution even if I call interrupt() method before its completion. Can someone please help me out with this? What am I missing?
Thanks in advance
It's not illegal to override interrupt, but I wouldn't recommend it. Perhaps a cleaner way to do this would be:
public class MyThread extends Thread {
private Process subprocess;
#Override
public void run() {
subprocess = Runtime.getRuntime().exec("myprocess.exe");
try {
subprocess.waitFor();
}
catch (InterruptedException e) {
subprocess.destroy();
}
/*
Some more statements
*/
}
}
Don't forget that you should also pull data from the subprocess output/error streams, otherwise you might wind up with full buffers and a blocked subprocess. It's OK to read from those streams and discard the data. I suspect the commons-io package has tools to make this a one-liner, otherwise it's a fairly simple method to write yourself.
I am trying to set up a method inside a class that implements the runnable interface that will set the interrupt status of that class. The reason i want to be able to do it from inside the class is there is some other clean up stuff that i need to take care of as well, and i would like to be able to do it all by calling one method instead of calling, for example:
Gui gui = new Gui() // class that implements runnable
Thread guiThread = new Thread(gui, "gui thread");
guiThread.start()
...
...
guiThread.interrupt();
gui.cancel();
Currently my cancel code looks like this, however it isn't correctly setting the interrupt status of this thread.
public void cancel()
{
Thread.currentThread().interrupt();
// other clean up code here.
}
Any advice on if/how i could get this working?
Thanks.
EDIT: I when i tried to get the cancel working, i commented out the guiThread.interrupt(), so that i wasn't just setting the status the reseting the status.
You want to simply call interrupt() - this will interrupt the guiThread, and not the calling thread. E.g.
public void cancel()
{
guiThread.interrupt();
// other clean up code here.
}
However, are you sure you want the cleanup code running on the calling thread? It is usually best to have the thread itself do its own cleanup. You don't know when the thread is interrupted and ready to be cleaned up. You could add a join() after interrupt() if the thread will exit when interrupted, but this is generally less preferable to simply having the thread itself do the cleanup. (Later, you may not even have separate threads for these tasks, but use a thread pool. Putting cleanup in with the task will make this much easier to manage.)
Finally, please be aware that your thread doesn't automatically interrupt and stop what it's doing - you need to call methods that check the interrupt status, such as Object.wait(), Thread.sleep() etc. or you can explicitly check the interrupt status via Thread.isInterrupted().
EDIT: It thought cancel() was on the guiThread. It's not, so I've changed the interrupt call.
If you want to do everything inside of cancel, just add a Thread parameter to it and pass a guiThread to it.
void cancel ( final Thread guiThread )
{
guiThread.interrupt( );
guiThread.join( );
// other cleanup code
...
}
Caller code
Gui gui = new Gui() // class that implements runnable
Thread guiThread = new Thread(gui, "gui thread");
guiThread.start()
...
...
gui.cancel( guiThread );
guiThread.interrupt(); should work fine, but if you want to interrupt your thread from inner class method, you should do:
public void cancel() {
if (isAlive()) {
this.interrupt();
}
}
or
public void cancel() {
if (!isInterrupted()) {
interrupt();
}
}