I just learned from sun's document that when i invoke thread.stop() method, the run() method will be terminated as the ThreadDeath error thrown out, and also release all the locks this thread holds, how to prove it?
I tried my test program, shown below:
public static void main(String[] args) {
final Object lock = new Object();
try {
Thread t = new Thread() {
public synchronized void run() {
try {
synchronized (lock) {
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++)
System.out.println("runing.." + i);
System.out
.println((System.currentTimeMillis() - start) / 1000);
}
} catch (Throwable ex) {
System.out.println("Caught in run: " + ex);
ex.printStackTrace();
}
}
};
t.start();
// Give t time to get going...
Thread.sleep(100);
t.stop(); // EXPECT COMPILER WARNING
} catch (Throwable t) {
System.out.println("Caught in main: " + t);
t.printStackTrace();
}
}
Only if i put an wait() in the run() method, then i can catch the ThreadDeath error, does anyone know the details of how jvm handle stop()?
public static void main(String[] args) {
final Object lock = new Object();
try {
Thread t = new Thread() {
public synchronized void run() {
try {
synchronized (lock) {
wait();
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++)
System.out.println("runing.." + i);
System.out
.println((System.currentTimeMillis() - start) / 1000);
}
} catch (Throwable ex) {
System.out.println("Caught in run: " + ex);
ex.printStackTrace();
}
}
};
t.start();
// Give t time to get going...
Thread.sleep(100);
t.stop(); // EXPECT COMPILER WARNING
} catch (Throwable t) {
System.out.println("Caught in main: " + t);
t.printStackTrace();
}
}
The simple answer is that the jvm has no reliable way to stop a thread. To stop or interrupt a thread, the target thread needs to cooperate by entering some interrupt-able state, such as sleep() or wait().
The Thread.stop() method has been deprecated for this reason (among others). See http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html for more details.
I do not think that I can explain better than Sun.
Here are the quotes from official Javadoc:
Deprecated. 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 threalink textd 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?.
See here:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html
that is because the thread executes before your current thread comes out of sleep and calls the t.stop.
The Thread.stop() doesn't stop a thread. Instead it call Thread.stop(new ThreadDeath()) which triggers the thread to throw this Error, which is silently ignored by default. i.e. if you throw any other Throwable the uncaughtException will print it to System.err. From ThreadGroup
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
There is nothing else special/magical about this error. Your thread will unwind in the same manner at it would if you threw new ThreadDeath(). For comparison, try
thread.stop(new RuntimeException());
The explanations about Thread.stop are pretty much right on. The proper way to build a cooperative runnable is as follows:
public class MyRunnable implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
public void run() {
// do stuff
if (stopped) {
// cleanup and return;
}
// do more stuff
if (stopped) {
// cleanup and return;
}
}
}
Runnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
r.stop();
t.join(); // if you want to wait for it to die.
OR
public class MyRunnable implements Runnable {
public void run() {
// do stuff
if (Thread.currentThread().isInterrupted()) {
// cleanup and return;
}
// do more stuff
if (Thread.currentThread().isInterrupted()) {
// cleanup and return;
}
}
}
Runnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
t.interrupt();
t.join(); // if you want to wait for it to die.
Note that in either case, you have strategic stop points in your code where you're checking to see if you should continue processing. The second approach has the advantage that interrupt aware operations like Thread.sleep and java.nio based I/O operations can be immediately interrupted and don't have to wait for your stop point. Instead they would throw an InterruptedException immediately (or in the case of NIO a ClosedByInterruptException). Note that standard java.io based I/O is not interrupt aware, and you'll have to wait for one of your coded stop points.
The real answer is that the stop method of class Thread calls the private stop1 method which is synchronized. As your implementation of the thread's run method is also synchronized the stop1 method cannot be entered until the run method is exited.
Related
I have the following code:
private static final AtomicBoolean shutdown = new AtomicBoolean(false);
public static void main(final String... args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
shutdown.set(true);
executorService.shutdown();
try {
executorService.awaitTermination(SHUTDOWN_TIMEOUT.getSeconds(), TimeUnit.SECONDS);
} catch (InterruptedException e) {
executorService.shutdownNow();
}
}));
executorService = Executors.newFixedThreadPool(2);
for (int i = 0; i < 2; i++) {
executorService.execute(create());
}
}
private static Runnable create() {
return new Runnable() {
#Override
public void run() {
while (!shutdown.get()) {
try {
Thread.sleep(5000);
System.out.println("Hatella" + Thread.currentThread().getName());
} catch (Throwable t) {
}
}
}
};
}
This code is working perfectly fine but I wanted to write this code in much simpler way so that I don't have to check the shutdown flag status in each while loop. Any idea what can I do to fix this and achieve the same thing.
shutdown() will only make the ExecutorService not accepting more tasks, but it will continue executing all pending tasks to the end. Since you actually want to stop executing tasks, you should use shutdownNow() in the first place, which will send an interruption signal.
public static void main(final String... args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
executorService.shutdownNow();
try {
executorService.awaitTermination(
SHUTDOWN_TIMEOUT.getSeconds(),TimeUnit.SECONDS);
} catch (InterruptedException e) {}
}));
for (int i = 0; i < 2; i++) {
executorService.execute(create());
}
}
private static Runnable create() {
return () -> {
while(!Thread.interrupted()) {
try {
Thread.sleep(5000);
System.out.println("Hatella" + Thread.currentThread().getName());
}
catch(InterruptedException ex) {
break;
}
catch (Throwable t) {
}
}
System.out.println("thread exit " + Thread.currentThread().getName());
};
}
The interruption flag can not only be queried via Thread.interrupted(), it will also make blocking actions like Thread.sleep(…) terminate earlier, reporting the situation via InterruptedException. In both cases, when Thread.interrupted() returned true or when the InterruptedException has been thrown, the interrupt status will be reset, so it’s crucial to either, react on it immediately or remember that you received it. So in the above example, catch(InterruptedException ex) contains a break, to end the loop.
But as shown, interruption does not terminate a thread but allows to react on it, e.g. by cleaning up when necessary, before exiting.
Note that when the only lengthy operations are the blocking ones, you don’t need to poll the interrupted status manually at all, e.g. the following would work too:
private static Runnable create() {
return () -> {
while(true) {
try {
Thread.sleep(5000);
System.out.println("Hatella" + Thread.currentThread().getName());
}
catch(InterruptedException ex) {
System.out.println("got "+ex+", "+Thread.interrupted());
break;
}
catch (Throwable t) {
}
}
System.out.println("thread exit");
};
}
Since this code does not check-and-reset the interrupted state via Thread.interrupted(), the signal will persist until the next invocation of Thread.sleep, which will be soon enough to appear as an immediate response, as the code executed between two sleep calls is short.
A) See Turning an ExecutorService to daemon in Java. Daemon threads will technically answer stated question (no requirement to poll a "shutdown" variable) but are probably a bad idea in any stateful context as the thread will be stopped in the middle of operation with no warning by the JVM (as soon as all non-daemon threads complete).
executorService = Executors.newFixedThreadPool(2, r -> {
Thread t = Executors.defaultThreadFactory().newThread();
t.setDaemon(true);
return t;
});
B) Another option in the real world (where an idle thread is likely blocking/sleeping on something) is to check shutdown only upon the InterruptedException which will occur upon executorService.shutdownNow()
I have 2 threads, the "main" thread which starts a secondary thread to run a little process.
The "main" thread must wait for the secondary thread for a few of seconds to complete the process, after that time, the "main" thread must start again no matter what happened with the process of the secondary thread.
If the secondary process ended earlier, the "main" thread must start to work again.
How can I start a thread from another, wait for the end of execution, and restart the thread after?
I have a code here, but the ExampleRun class, must wait, for example, 10 sec and start again, no matter what happend with MyProcess
public class ExampleRun {
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
System.out.println("Error");
}
}
}
}
public class MyProcess extends Thread {
public void run() {
System.out.println("start");
synchronized (this) {
for (int i = 0; i < 5; i++) {
try {
System.out.println("I sleep");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
System.out.println("Wake up");
notify();
}
}
}
The simplest way to achieve what you want is to use Thread.join(timeout).
Also, do not use synchronized, wait, or notify on Thread objects. This will interfere with the Thread.join implementation. See the documentation for details.
Here's what your main program would look like:
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
try {
t.join(10000L);
} catch (InterruptedException ie) {
System.out.println("interrupted");
}
System.out.println("Main thread resumes");
}
Note that when the main thread resumes after the join() call, it can't tell whether the child thread completed or whether the call timed out. To test this, call t.isAlive().
Your child thread of course could do anything, but it's important for it not to use synchronized, wait, or notify on itself. For example, here's a rewrite that avoids using these calls:
class MyProcess extends Thread {
public void run() {
System.out.println("MyProcess starts");
for (int i = 0; i < 5; i++) {
try {
System.out.println("MyProcess sleeps");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyProcess finishes");
}
}
You can do this with a simple lock method:
public static void main (String[] args)
{
// create new lock object
Object lock = new Object();
// create and start thread
Thread t = new Thread(() ->
{
// try to sleep 1 sec
try { Thread.sleep(1000); }
catch (InterruptedException e) { /* do something */ }
// notify main thread
synchronized (lock) { lock.notifyAll(); }
};
t.start();
// wait for second thread to finish
synchronized (lock)
{
while (t.isAlive())
lock.wait();
}
// second thread finished
System.out.println("second thread finished :)");
}
You could call Thread.join() on the Thread you want to wait for, per the Javadoc,
Waits for this thread to die.
Alternatively, you could use a Future and simply call get(), from its' Javadoc,
Waits if necessary for the computation to complete, and then retrieves its result.
class Thread3_1 extends Thread {
public static int count = 0;
String tname1;
public Thread3_1(String threadname) {
tname1 = threadname;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname1 + " : " + i);
count++;
if (count == 2) {
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
}
}
class Thread3_2 extends Thread {
String tname2;
public Thread3_2(String threadname) {
tname2 = threadname;
}
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2 + " : " + i);
if (i == 5) {
Thread.currentThread().interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
Thread is executing after giving interrupt()
Interrupting a thread just sets an interrupt flag to true for this thread.
It's the responsibility of the thread itself to regurlarly check the value of this flag and stop executing ASAP (by returning from the run() method) as soon as it's true.
When the interrupt flag is set while the thread is sleeping (or when it's blocked inside a bocking call like wait(), await(), etc.), an InterruptedException is thrown by the blocking method. It's also the responsibility of the thread to cacth this exception and stop executing ASAP.
Your first thread regularly checks the flag and exits when it's true, but fails to do so when an InterruptedException is caught.
Your second thread interrupts itself, but doesn't return from its run() method when it does so.
You interrupt Thread3_2 and not Thread3_1.
In the run method of Thread3_2 you are calling
Thread.currentThread().interrupt();
This will send an interrupt to the current executing thread and this is an instance of Thread3_2. If you want to interrupt Thread3_1 you need a reference to that thread.
For example:
class Thread3_2 extends Thread{
Thread threadToInterrupt;
public Thread3_2(Thread threadToInterrupt) {
this.threadToInterrupt = threadToInterrupt;
}
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2+ " : " +i);
if(i == 5){
threadToInterrupt.interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
The thread you are interrupting must be designed to deal with the interruption request, by exiting gracefully from the run() method. That means making sure that InterruptedExceptions cause the code to break out of loops. It also means checking the interrupted flag periodically inside loops. There are other scenarios which are harder to deal with, such as non-interruptible IO operations.
It is also a good practice that the target thread re-marks itself as interrupted, so that the callers up in the call stack also get an indication of the interruption (Use Thread.currentThread().interrupt() in catch statements).
As noted above you need to interrupt Thread3_1 and not Thread3_2.
After applying this fix you will still have one issue left:
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
So if at sleep interrupt happens, interrupt flag will be cleared and isInterrupted() method will return false, so below condition will not be met:
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
So you need to handle this in catch block as well, i.e. return if in catch (got interrupted)
From the Java Tutorials:
Many methods that throw InterruptedException, such as sleep, are
designed to cancel their current operation and return immediately when
an interrupt is received.
What if a thread goes a long time without invoking a method that
throws InterruptedException? Then it must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received.*
*In other words: Other methods that do not throw InterruptedException must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received.
Explained here: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Why doesn't thread wait for notify()? The thread starts and then goes to the waiting pool, but it proceeds to execute after that moment.
public class JavaApplication2 {
public static void main(String [] args) {
ThreadB b = new ThreadB();
synchronized(b) {
b.start();
try {
System.out.println("1");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
synchronized(this) {
total += 1;
//notify();
}
}
}
You are synchronizing on the thread object itself, which is wrong usage. What happens is that the dying thread-of-execution always calls notify on its Thread object: Thread.join relies on this. Therefore it is clear why you get the same behavior with and without your own notify in there.
Solution: use a separate object for thread coordination; this is the standard practice.
The method notifyAll() is invoked for the Thread object of the terminating thread. This fact is strangely documented in the description of the Thread.join, with the following sentence:
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Thus, if you don't explicitly read the description of join, which you don't necessarily have to, you don't get to know the reason for the strange behavior.
You cannot depend on not returning from wait until a notify: "interrupts and spurious wakeups are possible". In general, you should wrap a wait call in a loop while the thread should go on waiting.
If you try your code synchronizing on any object other that ThreadB you will find it never terminates. This is because there is a hidden call to notify.
Although I am not aware of anywhere that this is specified, Thread notifies itself when it ends. This is implicit in the way the join method is implemented. This is the code for join:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
(From the JDK7 source code)
As you can see, the calls to wait only make sense if somewhere there is a call to notify that is called after the thread ends. The same call to notify is what allows your program to terminate.
You have nested synchronized {} constructs in the two places. These constructs seem doing something weird: the thread does not react into notify at all and only resumes when ThreadB (b) terminates. Remove this:
public class JavaApplication2 {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println(" ### Waiting for notify");
synchronized (b) {
b.wait();
}
System.out.println(" ### Notified");
} catch (InterruptedException e) {
}
System.out.println("### Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
total += 1;
System.out.println(" *** Ready to notify in 5 secs");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** Notification sent");
synchronized (this) {
notify();
}
System.out.println(" *** 5 sec post notification");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** ThreadB exits");
}
}
The code above probably works correctly: with notify() present the main thread resumes after 5 seconds and before we see the message that ThreadB terminates. With notify() commented out the main thread resumes after 10 seconds and after the message about the termination of the ThreadB because notify() is called anywhay from the other code. Marko Topolnik explains why and from where this "behind the scene" notify() call comes from.
I was doing the same testing on the wait/notify opertaions while reading OCP SE 7, good catch. I think we should let the authoer to explain.
Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.
You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.
You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
See also Guava's TimeLimiter which uses an Executor behind the scenes.
It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps
There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time
I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}
Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}
You need a circuit breaker implementation like the one present in the failsafe project on GitHub.
Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.
Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.