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()
Related
Problem : I have an use case where I want to cancel a task that has already been submitted to an executor service. future.cancel() is not helpful to me as the task does not go to wait() / sleep() state during the execution. Also, adding isInterrupted() is not scalable because of the following reasons,
Many other services are called during the execution and using isInterrupted() before each call is ugly.
If suppose one of the service calls in one of the submitted tasks takes more than X milliseconds, I would want to abort the task and free up the tread.
Here is a sample code on how I am using future.cancel() right now. Is there a way where I can completely abort the submitted task / kill the thread executing the task in the main() function without disturbing the other submitted tasks.
public class Main {
ExecutorService executorService = newFixedThreadPool(10);
public static void main(String[] args) {
Future<Integer> test = new Main().sample();
try {
test.get(0, java.util.concurrent.TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
System.out.println("Throwing InterruptedException");
} catch (java.util.concurrent.ExecutionException e) {
System.out.println("Throwing ExecutionException");
} catch (java.util.concurrent.TimeoutException e) {
System.out.println("Throwing TimeoutException");
} finally {
System.out.println(test.cancel(true));
}
System.out.println("main() COMPLETED");
}
private Future<Integer> sample() {
return executorService.submit(() -> {
System.out.println("sample() STARTED");
anotherSample();
System.out.println("sample() COMPLETED");
return 1;
});
}
private void anotherSample() throws Exception {
System.out.println("anotherSample() STARTED");
for (int i = 0; i < 100000; i++) {
// do nothing
}
System.out.println("anotherSample() COMPLETED");
}
}
Output :
Throwing TimeoutException
sample() STARTED
anotherSample() STARTED
true
main() COMPLETED
anotherSample() COMPLETED
sample() COMPLETED
In the following code I want to terminate the Callable process submitted by ExecutorService. Currently the execution of the callable process is not terminating even though the shutdown called before the loop execution.
Any suggestion would be helpful.
package foundation.util.sql.parser;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) {
try {
final java.util.Map<String, ExecutorService> map = new HashMap<>();
ExecutorService service = Executors.newFixedThreadPool(1);
map.put("1", service);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println("Termination Initiated");
ExecutorService executorService = map.get("1");
System.out.println("ShutDown called");
if(!executorService.isShutdown())
{
executorService.shutdownNow();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
Future<Boolean> submit = service.submit(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
int j = 0;
System.out.println(Thread.currentThread().getName());
for (int i=0; i<5000;i++) {
//Some business Process.
j = i;
}
System.out.println("Test____"+ j);
return null;
}
});
thread.start();
submit.get();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When we call showDownNow() it doesn't terminate the running tasks, in fact
it just prevents waiting tasks from starting and attempts to stop currently executing tasks.
As per javadoc
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.
In your callable you are not responding/checking for the interrupts. You need check periodically if the interrupt flag is set to true. If so, do the necessary clean up if needed and terminate.
As an example, in your case you can consider checking the interrupt flag as below (or wherever applicable):
for (int i=0; i<5000;i++) {
//Some business Process.
if(Thread.currentThread().isInterrupted()) {
// do any cleanup and return from here.
return false;
}
j = i;
}
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.
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.
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.