RejectedExecutionException coming from single thread executor - java

Below is my method in which I have single thread executor to execute some task in the run method.
private void trigger(final Packet packet) {
// this line is throwing exception
Executors.newSingleThreadExecutor().execute(new Runnable() {
#Override
public void run() {
// some code here
}
});
}
Below is the exception I am getting and I am not sure why? What is the best way to fix this?
error= java.util.concurrent.RejectedExecutionException: Task com.abc.stuffProc$2#e033da0 rejected from java.util.concurrent.ThreadPoolExecutor#76c2da8f[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:628)
What happens if my trigger method is called many times and it is still working on the run method from my previous threads? Will it launch as many threads or it will wait for one thread to finish and then start another thread?

See here: What could be the cause of RejectedExecutionException
as you could see from the error log, your ThreadPoolExecutor is Terminated.
Maybe this is what you want:
private void trigger(final Packet packet) {
executor.execute(new Runnable() {
#Override
public void run() {
// some code here
}
});
}
private final ExecutorService executor = Executors.newFixedThreadPool(10);
EDIT Reproduce the Problem with:
public static void main(String[] args) {
final ExecutorTest et = new ExecutorTest();
for (int i = 0; i < 50000; i++) {
et.trigger(i);
}
System.out.println("Done");
}
private void trigger(int i) {
try {
Executors.newSingleThreadExecutor().execute(() -> {
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
} catch (final Exception e) {
System.out.println("Test " + i + " with " + Thread.activeCount());
e.printStackTrace();
}
}

Create ThreadPoolExecutor outside of your trigger method. You should not create newSingleThreadExecutor for every call.
private ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private void trigger(final Packet packet) {
executorService .execute(new Runnable() {
#Override
public void run() {
// some code here
}
});
}
Regarding your exception, please check execute method description.
public void execute(Runnable command)
Executes the given task sometime in the future. The task may execute in a new thread or in an existing pooled thread. If the task cannot be submitted for execution, either because this executor has been shutdown or because its capacity has been reached, the task is handled by the current RejectedExecutionHandler.
Since it's unbounded queue, most likely you have called shutdown some where else in your code.

Related

How to completely stop / terminate a task that has already been submitted to an ExecutorService in Java?

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

How to terminate callable process called by ExecutorService

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;
}

How one thread can wait until another one finishes to fire some actions

As shown below in the code, I am loading a heavy file on a worker thread fileThread, and while that thread loads the file, I created another thread fileLoadIndicator to show something like the busy indicator on the screen. What I am trying to do now is: after the fileLoadIndicator thread finishes, I want to enable a button, but only after the fileLoadIndicator thread is finished.
My attempts:
loadFile();// the very heavy file
/**
* The below thread "fileLoadIndicator"is to show busy indicator while our main file
that takes approx. 8 seconds to be loaded
*
*/
fileLoadIndicator = new Thread(fileLoadIndicatorRun);
fileLoadIndicator.start();
indicatorMonitor = new Thread(indicatorMonitorRun);
indicatorMonitor.start();
...
...
Runnable fileLoadIndicatorRun = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
statusarea.append(Log.w(TAG, "busyIndicatorRunnable", "Loading."));
StringBuilder sb = new StringBuilder(".");
do {
try {
fileThread.join(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sb.append(".");
statusarea.append(sb.toString());
} while (fileThread.getState() != State.TERMINATED);
//statusarea.append("/n");
}
};
Runnable indicatorMonitorRun = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
fileLoadIndicator.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setViewEnableState(Bpause, true);
}
};
But what happens in the indicatorMonitorRun is, the indicatorMonitor thread waits until the whole method loadFile(), which process the heavy file line by line and the whole process might takes 70 minutes, finishes. I just want to enable a button, only when the fileLoadIndicator thread finishes, and I should not wait until the whole file is loaded and processed which a very long time.
Kindly please let me know how can I do so.
I would suggest using ExecutorService to manage your thread pools and if you're using Java 8, take advantage of CompletableFuture as it simplifies these types of tasks without requiring complex thread wait/notify and java.util.concurrency types, for example:
package so.thread.wait;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class LongThreadWait {
public static void main(String[] args) throws Exception {
// thread pool for long running loaders
final ExecutorService fileLoaders = Executors.newCachedThreadPool();
// hook to be invoked when the file is done loading
final CompletableFuture<Long> completionFuture = new CompletableFuture<>();
completionFuture.thenAcceptAsync(LongThreadWait::completionConsumer);
fileLoaders.submit(new FileLoader(completionFuture));
Thread.sleep(TimeUnit.SECONDS.toMillis(3));
}
private static void completionConsumer(Long millis) {
System.out.println("Completed on Thread [" + Thread.currentThread().getName() + "] in " + millis + " ms");
}
private static class FileLoader implements Runnable {
private CompletableFuture<Long> completionFuture;
public FileLoader(CompletableFuture<Long> completionFuture) {
this.completionFuture = completionFuture;
}
#Override
public void run() {
long start = System.currentTimeMillis();
// load file for a long time
System.out.println("Loading file on Thread [" + Thread.currentThread().getName() + "]");
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
// invoke the completion future with the elapsed milliseconds
completionFuture.complete(end - start);
}
}
}
The CompletableFuture.thenAcceptAsync(..) by default runs the supplied hook in the default "ForkJoin" thread pool in the JVM, there is an optional second argument where you can supply your own ExecutorService to define what thread the completion hook is executed on.
This type of setup simplifies thread management and complex wait semantics.
You should also note that CompletableFuture has a comprehensive fluent API to make complex chaining of thread results simpler.
Consider using a CountDownLatch. Initialize this to 1. When your loading thread is done, it can call countDown. Your monitor thread can either poll count or simply await completion.
You could used a "ExecutorService" to create a thread pool, then monitor the threads and wait for the threads to terminate to enable the button.
class FileThreadThread implements Runnable {
public FileThreadThread() {
}
#Override
public void run() {
}
}
class FileLoadIndicatorRunThread implements Runnable {
private ExecutorService fileLoadIndicatorExecutor = null;
#Override
public void run() {
if (fileLoadIndicatorExecutor == null || fileLoadIndicatorExecutor.isShutdown()) {
fileLoadIndicatorExecutor = Executors.newCachedThreadPool(CustomizableThreadFactory.createSingleNamedFactory("FileLoaderThreadPool"));
}
for(int i=0; number_of_files; i++){
fileLoadIndicatorExecutor.execute(new FileThreadThread());
}
//Request executor shutdown after all threads are completed
fileLoadIndicatorExecutor.shutdown();
while (isRunning) {
boolean threadTerminated = fileLoadIndicatorExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
if(threadTerminated){
// enable a button
isRunning = false;
}
}
}
}

How to return from JUnit test to main method if part of test takes too long

I try to run junit from my main() method:
public static void main(String... args) throws ClassNotFoundException,
IOException {
//...
logger.debug("className " + className + "methodName " + methodName);
Request request = Request.method(Class.forName(className), methodName);
return new JUnitCore().run(request);
}
I have an E2E test with 10 commands (say). It is run by JUnit and I want to limit the run time of commands 3-5 to X millis (where X is determined at run time). If it runs longer than X I want to return to the main() and print something.
I have tried System.exit() but it closes the whole application. I tried:
public void setTimeOut(String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
//System.exit(2);
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
public void setTimeOut(final Thread thread, String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
thread.interrupt();
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
but the main thread continues to run the test even if exceeds the limit. What would you suggest?
Unit testing might not be the best approach to solving this sort of performance testing. However, if there's some reason this must be done, read on...
Use an ExecutorService to run the commands you want, with a given timeout. If the timeout expires, throw your own exception that you can catch in your main thread:
#Test
public void yourTest() throws Exception {
// Do commands 1-2
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Void> result = service.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
// call commands 3-5
return null;
}
});
try {
result.get(42, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
throw new YourOwnException();
}
service.shutdown();
// Do commands 6-10
}
One fairly simple mechanism is to use a BlockingQueue to indicate that the test completed. If you find it didn't you can then interrupt it. This will only work if the test correctly responds to being interrupted.
// Send FINISHED down this queue when test completes.
final BlockingQueue<Object> finished = new ArrayBlockingQueue<>(1);
// FINISHED cookie.
static final Object FINISHED = new Object();
public void test() throws InterruptedException {
Thread test = new Thread(new Runnable() {
#Override
public void run() {
// Do your stuff.
// ...
// Signal we finished.
finished.add(FINISHED);
}
});
// Start the test in it's own thread.
test.start();
try {
// Wait for your time.
if (FINISHED == finished.poll(5, TimeUnit.MILLISECONDS)) {
// It completed! No problems.
} else {
// It hasn't finished! Interrupt it.
test.interrupt();
};
} catch (InterruptedException ex) {
// We were interrupted! Do something.
test.interrupt();
// Rethrow it.
throw(ex);
}
}
You can extend this mechanism by adding a "Started" message too so you can ensure that the test thread gets at least a chance to run.

Run a new thread and don't wait this thread finish

I am new to the Threading, so if please give me an advice for my case.
I would like create a new thread to do something and I don't care this thread can do complete or not.
I intend to use ExecutorCompletionService to do my job but this class is not suitable for me. It must call take or poll to drain a queue to avoid memory leak. So, this means I must wait until the thread complete. I read this from this question
This is the current code
ExecutorService executor = Executors.newCachedThreadPool();
CompletionService<Entity> completion = new ExecutorCompletionService<>(executor);
DoSomeThingClass doSomething = getInstance();
completion.submit(doSomething);
executor.shutdown();
// Continue to do other job and I don't care whenever doSomeThing is complete.
// However when doSomeThing finish, I don't need to do anything to avoid memory leak
For that reason, please give me an approach for my case and some skeleton code for example.
Thank you so much
You can mark this thread as "Daemon". And when your main thread completed, your app will exit.
public static void main(String[] args)
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch(InterruptedException e) {}
System.out.println("Thread 2 is finished");
}
});
t.setDaemon(true);
t.start();
System.out.println("Thread 1 is finished");
}
You can use Spring TaskExecutor, it is very useful to raise a thread to run a task.
import org.springframework.core.task.TaskExecutor;
public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public MessagePrinterTask(String message) {
this.message = message;
}
public void run() {
System.out.println(message);
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}
You can check Spring Task Execution documentation here:
http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
Along with you code your Future concept
Future ft=completion.submit(doSomething);
ft.get(timeOut, TimeUnit.MILLISECONDS);
here you can specify Time to execute Thread if it fail to get execute thread get kill(not 100% sure)means it try to interrupt the thread and try to kill
I can resolve my problem as the following code
public static void main(
String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
} finally {
System.out.println("Thread 2 is finished");
}
}
});
executor.shutdown();
System.out.println("Thread 1 is finished");
}

Categories