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.
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 a ScheduledThreadPoolExecutor which has one thread and runs for every 30 seconds.
Now, if the current executing thread throws some exception, then I need to make sure that the next thread do not run and the the ScheduledThreadPoolExecutor is down.
How do I achieve this?
Catch the exception call shutdown/shutdownNow API in ExecutorService
shutdown()
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.
shutdownNow()
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
Refer to these post for more details with working code.
How to forcefully shutdown java ExecutorService
As a clean way, you can simply use a static accessed class to set/check the execution availability.
import java.util.concurrent.atomic.AtomicBoolean;
class ThreadManager
{
private static AtomicBoolean shouldStop = new AtomicBoolean(false);
public static void setExceptionThrown(boolean val)
{
shouldStop.set(val);
}
public boolean shouldExecuteTask()
{
return !shouldStop.get();
}
}
And a custom runnable implementation that allows you to check for the possibility to execute the task
abstract class ModdedRunnable implements Runnable
{
#Override
public void run()
{
if(ThreadManager.shouldExecuteTask())
{
try
{
runImpl();
}
catch(Exception t)
{
ThreadManager.setExceptionThrown(true);
}
}
}
public abstract void runImpl() throws Exception;
}
In my application , I have this logic when the user logins , it will call the below method , with all the symbols the user owns .
public void sendSymbol(String commaDelimitedSymbols) {
try {
// further logic
} catch (Throwable t) {
}
}
my question is that as this task of sending symbols can be completed slowly but must be completed , so is there anyway i can make this as a background task ??
Is this possible ??
please share your views .
Something like this is what you're looking for.
ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Runnable() {
public void run() {
sendSymbol();
}
});
Create an executor service. This will keep a pool of threads for reuse. Much more efficient than creating a new Thread each time for each asynchronous method call.
If you need a higher degree of control over your ExecutorService, use ThreadPoolExecutor. As far as configuring this service, it will depend on your use case. How often are you calling this method? If very often, you probably want to keep one thread in the pool at all times at least. I wouldn't keep more than 4 or 8 at maximum.
As you are only calling sendSymbol once every half second, one thread should be plenty enough given sendSymbols is not an extremely time consuming routine. I would configure a fixed thread pool with 1 thread. You could even reuse this thread pool to submit other asynchronous tasks.
As long as you don't submit too many, it would be responsive when you call sendSymbol.
There is no really simple solution. Basically you need another thread which runs the method, but you also have to care about synchronization and thread-safety.
new Thread(new Runnable() {
public void run() {
sendSymbol(String commaDelimitedSymbols);
}
}).start();
Maybe a better way would be to use Executors
But you will need to case about thread-safety. This is not really a simple task.
It sure is possible. Threading is the way to go here. In Java, you can launch a new thread like this
Runnable backGroundRunnable = new Runnable() {
public void run(){
//Do something. Like call your function.
}};
Thread sampleThread = new Thread(backGroundRunnable);
sampleThread.start();
When you call start(), it launches a new thread. That thread will start running the run() function. When run() is complete, the thread terminates.
Be careful, if you are calling from a swing app, then you need to use SwingUtil instead. Google that up, sir.
Hope that works.
Sure, just use Java Threads, and join it to get the results (or other proper sync method, depends on your requirements)
You need to spawn a separate thread to perform this activity concurrently. Although this will not be a separate process, but you can keep performing other task while you complete sending symbols.
The following is an example of how to use threads. You simply subclass Runnable which contains your data and the code you want to run in the thread. Then you create a thread with that runnable object as the parameter. Calling start on the thread will run the Runnable object's run method.
public class MyRunnable implements Runnable {
private String commaDelimitedSymbols;
public MyRunnable(StringcommaDelimitedSymbols) {
this.commaDelimitedSymbols = commaDelimitedSymbols;
}
public void run() {
// Your code
}
}
public class Program {
public static void main(String args[]) {
MyRunnable myRunnable = new MyRunnable("...");
Thread t = new Thread(myRunnable)
t.start();
}
}
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.
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();
}
}