How to run a method for a particular duration of time? - java

I read this
How do you know if the method successfully completed or if it was interrupted?
Edit: To make the question more clear and specific.Below is my code .. I want to execute the test.java file for and get its runtime.. However if it takes more than 1 sec I want to display an error message and stop it there itself ..
public class cl {
public static void main(String args[])throws IOException
{
String s=null;
Process p=Runtime.getRuntime().exec("javac C:\\Users\\Lokesh\\Desktop\\test.java");
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
Timer timer=new Timer(true);
InterruptTimerTask interruptTimerTask=new InterruptTimerTask(Thread.currentThread());
timer.schedule(interruptTimerTask,1);
try{
Runtime.getRuntime().exec("java C:\\Users\\Lokesh\\Desktop\\test");
}
catch (Exception e)
{
e.printStackTrace();
}
finally {
timer.cancel();
}
}
static class InterruptTimerTask extends TimerTask {
private Thread thread;
public InterruptTimerTask(Thread thread)
{
this.thread=thread;
}
#Override
public void run()
{
thread.interrupt();
}
}
}

The easiest way to understand what terminated your thread is to have a boolean flag, call it 'interrupted', and set it when you catch the InterruptedException. Assuming that your code doesn't do anything else that can throw that exception, you can check the value of the flag in the code that follows.

As the exapmle:
try {
Thread.sleep(10000);
// method successfully completed
} catch (InterruptedException ex) {
// method was interrupted. You can try sleep some more time if you want
}
Thread.sleep() is one of methods that can be interrupted. There can be any another method instead, or even your's method if it checks it's interrupted state. If your method realized that someone wants to interrupt it, it must throw InterruptedException (not must, sometimes it will be better to continue running).
The Interrupt Status Flag
The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.

Related

Stopping a Thread / Threads calls interrupt on itself after crash?

I am currently running a Thread from a Service to do some background work.
Now there is the possibility that the Thread crashes or I want to
interrupt the thread from the Service. So how am I supposed to:
stop the Thread realiable, (hard)
catch exceptions and call the Service about the crash
handle InterruptedException if interrupted while sleep()
is Thread.isInterrupted a good way to detect if the Thread stopped?
What I have done so far is the following:
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
doMyBackgroundWork();
sleep();
}
}catch(Exception e){
ExceptionHandler.logAndSendException(e);
Thread.currentThread().interrupt();
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
LOG.i("Thread stops now.");
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
//what to do here? it can happen because I stopped it myself
}
}
So at first I am running my Thread until it gets interrupted.
If any exception occurs, I want to start a new Thread, therefore
my Service implements a listener interface and I call it, once an
Exception is thrown. I know that catching everything is discouraged,
but I need to know if the Thread stops, without polling Thread.isAlive()
all the time.
Additionally to my four questions above:
is my code reliable and does what I need?
is it ok to call interrupt on the Thread itself?
Thanks!
You are not actually interrupting your own thread because the catch block is outside of the while loop. Therefore, any exception would stop execution immediately.
Interruption is essentially just a request (usually from another thread) to stop doing what you are doing. The thread is free to ignore it and keep doing what it is doing. Normally you have to throw an exception in response to an interrupt, or stop execution some other way such as just breaking from the loop (you need this around the //what to do here? comment). It so happens that some library methods are "responsive to interruption" meaning they will throw an exception if the thread is ever interrupted, such as Thread.sleep(), which you will most likely have in your sleep call.
I recommend picking Java Concurrency In Practice. Among the excellent concurrency material, there is a chapter on interrupts which is very helpful.
EDIT:
I would remove the code where you interrupt your own thread. You will also need to rethrow the InterruptedException as a runtime exception to get out of the execution loop. Usually people will create a new Exception that extends RuntimeException that is something like MyInterruptedException. You can then add it to the catch block around your loop so that you know when the thread was interrupted vs execution failed.
As a general example you can do something like this:
public void run() {
try {
while (true) {
// check for interrupts in the loop, or somewhere in the work method
if (Thread.interrupted()) {
throw new MyInterruptedException("Important thread interrupted.");
}
doMyBackgroundWork();
sleep();
}
}
catch(Exception e){
ExceptionHandler.logAndSendException(e);
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
catch(MyInterruptedException i) {
LOG.i("Execution stopping because of interrupt.");
}
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
throw new MyInterrptedException(e);
}
}
we have a nice and effective method called stop()(Thread.stop(void):void) which is deprecated, but it works and it's lovely.
Note that stop() throws ThreadDeath at the target thread which is not an exception(and it could any other throwable too), but an Error, so your code will not catch any signal about this.
public void run() {
try {
while (<<using_a_volatile_bool_type_is_better>>) {
...
}
}catch(Throwable t){/**/}/*use throwable instead of exception.*/}
}
Beside dear friend stop() we also have pause() method too, and it really pauses the target thread.
Not just one solution out there, but if it's really critical to keep thread run and run the emergency(or itself) just after any crash, you may run it as a separately app/process, plus get progress status(if any) that ensures you the target thread/app is not freezed(blocked,...)

What is wrong with it?

I've seen a lot of example for wait and notify, but still I have a problem.
public class Main(){
public static void main(String args[]) throws Exception {
MyThread s = new MyThread();
s.start();
}
}
class MyThread extends Thread {
public void run() {
k();
}
public synchronized void k() {
System.out.println("before wait");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("do something after wait");
}
public synchronized void m() {
for (int i=0;i<6;i++)
System.out.println(i);
notify();
}
}
The only output I get when run the program is: "before wait".
The thread you create in main invokes MyThread#k() which goes into a wait. At that point, that thread will do nothing else until it is awakened or interrupted. But the only place in your code where it could possibly be awakened is the notify in MyThread#m(). Since nothing in your program calls that method, the thread can never be awoken.
What you probably want is to add a call to s.m() right after s.start() in your main program. That way your main thread will execute the notify that's needed to wake up your thread.
Unfortunately, that's very unlikely to work. The problem is that s.start() causes your created thread to become ready to run, but it doesn't necessarily run immediately. It could well happen that your call to s.m() will complete before the created thread does anything. And then you'll still have exactly the same result as before, except that you'll see the integers 0..6 printed out before before wait. The notify will do nothing, because the child thread has not yet performed its wait. (And by the way, since both MyThread#k() and MyThread#m() are both synchronized, increasing your loop limit in MyThread#m() won't change a thing... the child thread won't be able to enter MyThread#k() while MyThread#m() is running. You could improve that by putting the notify in a sycnchronized block rather than making all of MyThread#m() synchronized.)
You can try to get around this by adding Thread.sleep(1000) before s.m() in your main program. That will almost certainly work because your main thread will yield execution, giving your JVM the opportunity to schedule the child thread for some useful work. By the time the main thread wakes out of its sleep and performs its s.m() call, the child will probably have executed its wait and you will then see your do something after wait message.
But that's still pretty crummy, because it still depends on scheduling events that you don't really have any control over. There's still no guarantee that the wait will happen before the notify.
This is why when using wait/notify you should generally arrange for there to be some sort of reliable test as to whether whatever you're waiting to be done has actually occurred. This should be a condition that, once it turns turns true, will remain true at least until the test has been subsequently performed. Then your typical wait loop looks something like this:
while (!isDone()) {
synchronized(monitorObject) {
try {
monitorObject.wait();
} catch (InterruptedException e) {
}
}
}
Putting the whole thing in a loop takes care of premature waking, e.g. due to InterruptedException.
If the required work has already occurred by the time this code is executed, no wait occurs, and the notify executed by the code that did the work was a no-op. Otherwise, this code waits, and the code completing the work will eventually do a notify which will wake this code up as required. Of course, it's critical that, at the time the notify is performed, the wait condition (isDone() above) be true and remain true at least until tested.
Here's a corrected version of your code that incorporates a proper wait loop. If you comment out the Thread.sleep() call, you will likely not see the waiting message, because the work will complete before the wait loop even starts. With the sleep included, you'll probably see the waiting message. But either way, the program will work properly.
public static void main(String[] argv) throws Exception {
MyThread s = new MyThread();
s.start();
Thread.sleep(1000);
s.m();
}
class MyThread extends Thread {
#Override
public void run() {
k();
}
private boolean done = false;
public void k() {
System.out.println("before wait");
while (!done) {
System.out.println("waiting");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
System.out.println("do something after wait");
}
public void m() {
for (int i = 0; i < 6; i++) {
System.out.println(i);
}
synchronized (this) {
done = true;
notify();
}
}
}
The problem is, that you're not calling your m method, so notify is never called, so your thread sleeps forever. You could call it in main, after the start, using s.m():
MyThread s = new MyThread();
s.start();
s.m();
Maybe you should sleep for a little time before calling the m method, as it could run sooner than k in the thread:
s.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// nothing to do
}
s.m();
Not closely related to the question, but a throws declaration in main is not very advisable, even a generated printStackTrace is better than throwing the exception away.

Interrupting a normally running thread in java

I am trying to interrupt a normally running thread (which is not in sleep() or wait() state) .
while going through in net i got to know interrupting a normally running thread will just set the flag true and continue the process.
Code snippet is
one.java
......
......
actionperformedmethod {
if (actionCmd.equals("cancel")) {
try {
r1.stop(); // to two.java
} catch (InterruptedException ex) {
....
....
}
}
}
in two.java
.....
.....
stop method() throws InterruptedException{
if(!(t.isInterrupted())){
t.interrupt();
throw new InterruptedException();
}
}
from two.java when i throw InterruptedException i can able to get the exception block at one.java , but how do i stop the thread after that because even after that thread seems to continue the normal process.
Am new to thread concepts please help..
The interrupt() method is co-operative rather than pre-emptive - the background task needs to actively check Thread.interrupted() at suitable intervals, and take action to shut itself down cleanly.
public void run() {
openSomeResources();
try {
while(notFinished) {
if(Thread.interrupted()) return;
doSomeStuff();
}
} finally {
closeTheResources();
}
}
In this example if the thread is interrupted in the middle of doSomeStuff() then it will complete the current "iteration" before responding to the interruption. Getting the correct balance between responding promptly to an interrupt on the one hand, and responding only at a safe point in the execution on the other hand, is something that is inherently specific to the particular task - there is no one-size-fits-all answer.
Note however that any blocking method that throws an InterruptedException will reset the interrupt flag when this exception is thrown. Therefore in order for this sort of checking to work you must re-interrupt yourself whenever you receive an InterruptedException
try {
Thread.sleep(3000);
} catch(InterruptedException e) {
// we were interrupted - set the flag so the next interrupted() check will
// work correctly.
Thread.currentThread().interrupt();
}
Interrupt will not stop the thread. it just sets the flag to true to signal the thread to stop the execution soon.
to stop the execution
add global variable as
private volatile boolean exit = false;
and
you add one method in your 2nd class
public void requestExit(){
exit = true;
}
inside run () of your thread do something like this
if (exit == true){
return;
}
whenever you want to call just call this method requestExit() from your main() or wherever you want to stop
this is the best way to stop the thread.. using stop() on thread is dangerous as it does not clear any resources and its not advisable to use even by oracle hence deprecated.
let me know for any issues
Threads are only running whilst their run() method is on the stack so usually people put a while(true) inside the run method, all you need to do in you thread to stop it is to return somewhere in the run method or break the loop then as soon as the run() method is no longer running the thread has been stopped.

Do I need to check for Thread.isAlive() here?

In a web controller, I have a parent thread that receives requests. Some requests take a long time to process. To prevent clients from timing out, I set up the parent thread to send back a byte every 2 seconds while a child thread is doing the time-consuming part of the operation.
I want to make sure I'm accounting for all possible cases of the child thread dying, but I also don't want to put in any extraneous checks.
Here is the parent thread:
// This is my runnable class
ProcessorRunnable runnable = new ProcessorRunnable(settings, Thread.currentThread());
Thread childThread = new Thread(runnable);
childThread.start();
boolean interrupted = false;
while (!runnable.done) { // <-- Check in question
outputStream.write(' ');
outputStream.flush();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// If the runnable is done, then this was an expected interrupt
// Otherwise, remember the interruption and re-interrupt after processing is done
// Or with self so that a later expected interrupt won't clear out an earlier unexpected one
interrupted = interrupted || !runnable.done;
}
}
if (runnable.runtimeException != null) {
LOG.error("Propagating runtime exception from thread");
throw runnable.runtimeException;
}
// ... Further processing on the results provided by the child thread
And here's ProcessorRunnable:
private volatile boolean done;
private volatile Result result;
private volatile RuntimeException runtimeException;
// ...
public void run() {
done = false;
try {
result = myService.timeConsumingOperation(settings);
} catch (RuntimeException e) {
runtimeException = e;
} finally {
done = true;
parentThread.interrupt();
}
}
My question is, would adding && Thread.isAlive() check in the parent thread's main loop buy me anything?
It seems that setting done = true in the finally block should do the trick, but are there some cases where this child thread could die without notifying the parent?
The finally in the child thread will always execute before it finishes. Even if that thread is interrupted or stopped, this happens via an exception that bubbles up the call stack and triggers all finallys. So, done will always be true if the child thread is interrupted.
For background tasks like this you may want to use an ExecutorService instead of raw threads. You can submit a Runnable to an ExecutorService and just call get() on the returned future to block until it is done. If you want to print out spaces while you are waiting, you can use a loop, calling the get() version with a timeout.

Thread Blocks in server mode

This method notifes an event loop to start processing a message. However, if the event loop is already processing a message then, this method blocks until it receives a notification of completed event processing (which is triggered at the end of the event loop).
public void processEvent(EventMessage request) throws Exception {
System.out.println("processEvent");
if (processingEvent) {
synchronized (eventCompleted) {
System.out.println("processEvent: Wait for Event to completed");
eventCompleted.wait();
System.out.println("processEvent: Event completed");
}
}
myRequest = request;
processingEvent = true;
synchronized (eventReady) {
eventReady.notifyAll();
}
}
This works in client mode. If I switch to server mode and the time spent in the event loop processing the message is too quick, then the method above blocks forever waiting for the event to completed. For some reason the event complete notification is sent after the processingEvent check and before the eventCompleted.wait(). It makes no difference if I remove the output statements. I can not repeat the same problem in client mode.
Why does this only happen in server mode and what can I do to prevent this happening?
Here is the eventReady wait and eventCompleted notification:
public void run() {
try {
while (true) {
try {
synchronized (eventReady) {
eventReady.wait();
}
nx.processEvent(myRequest, myResultSet);
if (processingEvent > 0) {
notifyInterface.notifyEventComplete(myRequest);
}
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
notifyInterface.notifyException(e, myRequest);
} finally {
processingEvent--;
synchronized (eventCompleted) {
eventCompleted.notifyAll();
}
}
} // End of while loop
} catch (InterruptedException Ignore) {
} finally {
me = null;
}
Here is revised code which seems to work without the deadlock problem - which BTW happened in client mode randomely after about 300 events.
private BlockingQueue<EventMessage> queue = new SynchronousQueue<EventMessage>();
public void processEvent(EventMessage request) throws Exception {
System.out.println("processEvent");
queue.put(request);
}
public void run() {
try {
while (true) {
EventMessage request = null;
try {
request = queue.take();
processingEvent = true;
nx.processEvent(request, myResultSet);
notifyInterface.notifyEventComplete(request);
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
notifyInterface.notifyException(e, request);
} finally {
if (processingEvent) {
synchronized (eventCompleted) {
processingEvent = false;
eventCompleted.notifyAll();
}
}
}
} // End of while loop
} catch (InterruptedException Ignore) {
} finally {
me = null;
}
}
If you call notifyAll and no thread is wait()ing, the notify is lost.
The correct approach is to always change a state, inside the synchronized block, when calling notify() and always check that state, inside the synchronized block, before calling wait().
Also your use of processingEvent doesn't appear to be thread safe.
Can you provide the code which waits on eventReady and notifies eventCompleted?
Your program can happen to work if your speed up or slow down your application just right e.g. if you use -client, but if you use a different machine, JVM or JVM options it can fail.
There are a number of race conditions in your code. Even declaring processingEvent volatile or using an AtomicBoolean won't help. I would recommend using a SynchronousQueue which will block the event until the processer is ready for it. Something like:
private final BlockingQueue<Request> queue = new SynchronousQueue<Request>();
...
// this will block until the processor dequeues it
queue.put(request);
Then the event processor does:
while (!done) {
// this will block until an event is put-ed to the queue
Request request = queue.take();
process the event ...
}
Only one request will be processed at once and all of the synchronization, etc. will be handled by the SynchronousQueue.
If processingEvent isn't declared volatile or accessed from within a synchronized block then updates made by one thread may not become visible to other threads immediately. It's not clear from your code whether this is the case, though.
The "server" VM is optimised for speed (at the expense of startup time and memory usage) which could be the reason why you didn't encounter this problem when using the "client" VM.
There is a race condition in your code that may be exasperated by using the server VM, and if processingEvent is not volatile then perhaps certain optimizations made by the server VM or its environment are further influencing the problem.
The problem with your code (assuming this method is accessed by multiple threads concurrently) is that between your check of processingEvent and eventCompleted.wait(), another thread can already notify and (I assume) set processingEvent to false.
The simplest solution to your blocking problem is to not try to manage it yourself, and just let the JVM do it by using a shared lock (if you only want to process one event at a time). So you could just synchronize the entire method, for instance, and not worry about it.
A second simple solution is to use a SynchronousQueue (this is the type of situation it is designed for) for your event passing; or if you have more executing threads and want more than 1 element in the queue at a time then you can use an ArrayBlockingQueue instead. Eg:
private SynchronousQueue<EventMessage> queue = new SynchronousQueue<EventMessage>();
public void addEvent(EventMessage request) throws Exception
{
System.out.println("Adding event");
queue.put(request);
}
public void processNextEvent()
{
EventMessage request = queue.take();
processMyEvent(request);
}
// Your queue executing thread
public void run()
{
while(!terminated)
{
processNextEvent();
}
}

Categories