Java timeout multiple tasks in parallel - java

What is the best practice approach to launch a pool of 1000's of tasks (where up to 4 should be able to execute in parallel) and automatically timeout them if they take more than 3 seconds (individually)?
While I found that ExecutorService seems to be helpful (see SSCE from another post below), I don't see how to make this work for multiple tasks running in parallel (as the future.get(3, TimeUnit.SECONDS) is executing on the same thread than the one launching the tasks, hence no opportunity to launch multiple tasks in parallel):
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
#Override
public String call() throws Exception {
Thread.sleep(4000); // Just to demo a long running task of 4 seconds.
return "Ready!";
}
}
Thanks!

If you have to monitor each task to kill it when it exceeds the timeout period, either
the task itself has to keep track of time and quit appropriately, OR
you have to create a second watchdog thread for every task. The watchdog thread sets a timer and sleeps, waking up after the timeout interval expires and then terminating the task if it's still running.

This is a tricky one. Here’s what I came up with:
public class TaskQueue<T> {
private static final Logger logger =
Logger.getLogger(TaskQueue.class.getName());
private final Collection<Callable<T>> tasks;
private final int maxTasks;
private int addsPending;
private final Collection<T> results = new ArrayList<T>();
private final ScheduledExecutorService executor;
public TaskQueue() {
this(4);
}
public TaskQueue(int maxSimultaneousTasks) {
maxTasks = maxSimultaneousTasks;
tasks = new ArrayDeque<>(maxTasks);
executor = Executors.newScheduledThreadPool(maxTasks * 3);
}
private void addWhenAllowed(Callable<T> task)
throws InterruptedException,
ExecutionException {
synchronized (tasks) {
while (tasks.size() >= maxTasks) {
tasks.wait();
}
tasks.add(task);
if (--addsPending <= 0) {
tasks.notifyAll();
}
}
Future<T> future = executor.submit(task);
executor.schedule(() -> future.cancel(true), 3, TimeUnit.SECONDS);
try {
T result = future.get();
synchronized (tasks) {
results.add(result);
}
} catch (CancellationException e) {
logger.log(Level.FINE, "Canceled", e);
} finally {
synchronized (tasks) {
tasks.remove(task);
if (tasks.isEmpty()) {
tasks.notifyAll();
}
}
}
}
public void add(Callable<T> task) {
synchronized (tasks) {
addsPending++;
}
executor.submit(new Callable<Void>() {
#Override
public Void call()
throws InterruptedException,
ExecutionException {
addWhenAllowed(task);
return null;
}
});
}
public Collection<T> getAllResults()
throws InterruptedException {
synchronized (tasks) {
while (addsPending > 0 || !tasks.isEmpty()) {
tasks.wait();
}
return new ArrayList<T>(results);
}
}
public void shutdown() {
executor.shutdown();
}
}
I suspect it could be done more cleanly using Locks and Conditions instead of synchronization.

Related

ScheduledExecutorService is not shutting down

I need to stop all the scheduled runnables when shutting down this executor I save the scheduled futures in a list when using execute(Runnable runnable), however, this does not work, the runnables are still being runned after calling shutdown but i'm in fact stopping them using scheduledFutures.forEach(scheduledFuture -> scheduledFuture.cancel(false)) in that method, why does this happen?.
public class ThreadPool {
private final ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
private final List<ScheduledFuture<?>> scheduledFutures = new ArrayList<>();
public ThreadPool(ScheduledThreadPoolExecutor scheduledThreadPoolExecutor) {
this.scheduledThreadPoolExecutor = scheduledThreadPoolExecutor;
}
public void execute(Runnable runnable) {
scheduledFutures.add(
scheduledThreadPoolExecutor.scheduleWithFixedDelay(runnable, 0, 20, TimeUnit.SECONDS));
}
public void shutdown() {
scheduledFutures.forEach(scheduledFuture -> scheduledFuture.cancel(false));
scheduledThreadPoolExecutor.shutdown();
try {
if (scheduledThreadPoolExecutor.awaitTermination(1, TimeUnit.SECONDS)) {
return;
}
scheduledThreadPoolExecutor.shutdownNow();
} catch (Exception exception) {
Thread.currentThread().interrupt();
}
}

Trigger SheduledExecutor with blockingQueue Java

I'm currently working on java application which has a scenario of multiple producers adding tasks to a queue and whenever queue is not empty tasks should be executed at predefined rate. (using multiple threads to maintain execution rate) After executing the available tasks executor has to wait till tasks available in the queue again.
I know blockingQueue can be used to triggering part in here and ScheduledExecutorService for execute tasks at fixed rate. But I could not find a way to link ability of both of this for my need. So I would be very thankful if you could give me any suggestion to make this happen.
You need the task queue to be accessible by both the producer and consumer threads. I've written a basic program to demonstrate this, but I'll let you play around with the BlockingQueue API and the ScheduledExecutor as per your needs:
import java.util.concurrent.*;
public class ProducerConsumer {
private static final BlockingQueue<Integer> taskQueue = new LinkedBlockingQueue<>();
public static void main(String[] args) {
ExecutorService consumers = Executors.newFixedThreadPool(3);
consumers.submit(new Consumer());
consumers.submit(new Consumer());
consumers.submit(new Consumer());
ExecutorService producers = Executors.newFixedThreadPool(2);
producers.submit(new Producer(1));
producers.submit(new Producer(2));
}
private static class Producer implements Runnable {
private final int task;
Producer(int task) {
this.task = task;
}
#Override
public void run() {
System.out.println("Adding task: " + task);
taskQueue.add(task); // put is better, since it will block if queue is full
}
}
private static class Consumer implements Runnable {
#Override
public void run() {
try {
Integer task = taskQueue.take(); // block if there is no task available
System.out.println("Executing task: " + task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This is the way I could come up with as a solution. It looks little bit rusty but I have tested this and the code is working.
package test;
import java.util.concurrent.*;
public class FixedRateConsumer {
private BlockingQueue<String> queue = new ArrayBlockingQueue<>(20);
private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(5);
private boolean continueRunning = true;
public void executeInBackGraound() throws InterruptedException, ExecutionException {
while (continueRunning) {
String s = queue.take();
Worker w = new Worker(s);
ScheduledFuture future = executorService.scheduleAtFixedRate(w, 0, 1, TimeUnit.SECONDS);
w.future = future;
try {
if (!future.isDone()) {
future.get();
}
} catch (CancellationException e) {
// Skipping
}
}
}
public void setContinueRunning(boolean state) {
continueRunning = state;
}
public void addConsumableObject(String s) throws InterruptedException {
queue.put(s);
}
private void consumeString(String s) {
System.out.println("Consumed -> " + s + ", ... # -> " + System.currentTimeMillis() + " ms");
}
private class Worker implements Runnable {
String consumableObject;
ScheduledFuture future;
public Worker(String initialConsumableObject) {
this.consumableObject = initialConsumableObject;
}
#Override
public void run() {
try {
if (consumableObject == null) {
consumableObject = queue.take();
}
consumeString(consumableObject);
consumableObject = null;
if (queue.isEmpty()) {
if (future == null) {
while (future == null) {
Thread.sleep(50);
}
}
future.cancel(false);
}
} catch (Exception e) {
System.out.println("Exception : " + e);
}
}
}
}

JAVA pass a method from outside class to the ThreadPool.submit()

I don't have previous experience with JAVA's concurrency, but ever done the same in C#.
My task
To create a "worker" class for easy multi-threading (creating continuous threads) managing in my applications.
what i want to have as result(usage example):
Worker worker = new Worker();
worker.threadCount = 10;
worker.doWork(myMethod);
worker.Stop();
to be able to use it in any class in my app, accepting 'void' methods as 'worker.doWork(myMethod);' argument.
What did i done from my researches on question:
class Worker
package commons.Threading;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
public class Worker {
static Boolean IsRunning = true;
public static int threadCount = 2;
static ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(threadCount);
public void doWork(**argument method**) throws IOException, InterruptedException {
while (IsRunning) {
threadPool.submit(new Runnable() {
**argument method**
});
Thread.sleep(1000);
}
}
public static void Stop(){
IsRunning = false;
threadPool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
threadPool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
threadPool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
}
ErrorReportingThreadPoolExecutor
package commons.Threading;
import java.util.concurrent.*;
public class ErrorReportingThreadPoolExecutor extends ThreadPoolExecutor {
public ErrorReportingThreadPoolExecutor(int nThreads) {
super(nThreads, nThreads,
0, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
#Override
protected void afterExecute(Runnable task, Throwable thrown) {
super.afterExecute(task, thrown);
if (thrown != null) {
// an unexpected exception happened inside ThreadPoolExecutor
thrown.printStackTrace();
}
if (task instanceof Future<?>) {
// try getting result
// if an exception happened in the job, it'll be thrown here
try {
Object result = ((Future<?>)task).get();
} catch (CancellationException e) {
// the job get canceled (may happen at any state)
e.printStackTrace();
} catch (ExecutionException e) {
// some uncaught exception happened during execution
e.printStackTrace();
} catch (InterruptedException e) {
// current thread is interrupted
// ignore, just re-throw
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) throws InterruptedException {
// replace
// ExecutorService threadPool = Executors.newFixedThreadPool(2);
// with
ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(2);
while (true) {
threadPool.submit(new Runnable() {
#Override public void run() {
System.out.println("Job is running...");
if (Math.random() < 0.5) {
int q = 1 / 0;
}
System.out.println("Job finished.");
}
});
Thread.sleep(1000);
}
}
}
So, the question is - how do i pass 'void' method from outside class here threadPool.submit(new Runnable() { here });
You could pass the Runnable itself is a parameter,
public void doWork(Runnable runnable) throws IOException, InterruptedException {
while (IsRunning) {
threadPool.submit(runnable);
Thread.sleep(1000);
}
}
Runnable is a functional interface,it has a single method run that takes no-param and returns void, and hence you can use it as a function.
Runnable runnable = new Runnable(){
public void run(){
// do work
}
};
doWork(runnable);
You can express it more concisely if you are on Java 1.8
Runnable runnable = ()->{/**do work*/};
doWork(runnable);

Java asynchronous execution increases CPU 100%

Introduction:
I've developed a class which would accept number of Tasks, execute them in parallel and await for results particular amount of time. If some of the tasks failed to finish by given timeout it will interrupt entire execution and return only available results.
Issue:
All works fine at the beginning but after some time CPU usage increases until 100% and application obviously fails to response.
Could you please try to help me find an issue or suggest better solution how I could achieve the same goal?
Code:
TaskService.java
public abstract class TaskService {
private static final org.slf4j.Logger InfoLogger = LoggerFactory.getLogger("InfoLogger");
private static final org.slf4j.Logger ErrorLogger = LoggerFactory.getLogger("ErrorLogger");
#Autowired
private TimeLimiter timeLimiter;
public List<TaskResult> execute(TaskType taskType, TimeUnit timeUnit, long timeout, final Task... tasks){
final List<TaskResult> taskResultsStorage = new ArrayList<>();
try {
timeLimiter.callWithTimeout(new Callable<List<TaskResult>>() {
#Override
public List<TaskResult> call() throws Exception {
return run(taskResultsStorage, tasks);
}
}, timeout, timeUnit, true);
} catch (UncheckedTimeoutException e) {
String errorMsg = String.format("Time out of [%s] [%s] has been exceeded for task type:[%s]", timeout, timeUnit.name(), taskType.name());
ErrorLogger.error(errorMsg, e);
} catch (Exception e) {
String errorMsg = String.format("Unexpected error for task type:[%s]", taskType.name());
ErrorLogger.error(errorMsg, e);
}
return taskResultsStorage;
}
protected abstract List<TaskResult> run(List<TaskResult> taskResults,Task... tasks) throws ExecutionException, InterruptedException;
}
AsynchronousTaskService.java
public class AsynchronousTaskService extends TaskService {
private CompletionService<TaskResult> completionService;
public AsynchronousTaskService(ThreadExecutorFactory threadExecutorFactory){
this.completionService = new ExecutorCompletionService<TaskResult>(threadExecutorFactory.getExecutor());
}
#Override
protected List<TaskResult> run(List<TaskResult> resultStorage, Task... tasks) throws ExecutionException, InterruptedException {
List<Future<TaskResult>> futureResults = executeTask(tasks);
awaitForResults(futureResults, resultStorage);
return resultStorage;
}
private List<Future<TaskResult>> executeTask(Task... tasks){
List<Future<TaskResult>> futureTaskResults = new ArrayList<>();
if(tasks!=null) {
for (Task task : tasks) {
if (task != null) {
futureTaskResults.add(completionService.submit(task));
}
}
}
return futureTaskResults;
}
private void awaitForResults(List<Future<TaskResult>> futureResults, List<TaskResult> resultStorage) throws ExecutionException, InterruptedException {
int submittedTasks = futureResults.size();
int taskCompleted = 0;
if(futureResults != null){
while(taskCompleted < submittedTasks){
Iterator<Future<TaskResult>> it = futureResults.iterator();
while(it.hasNext()){
Future<TaskResult> processingTask = it.next();
if(processingTask.isDone()){
TaskResult taskResult = processingTask.get();
resultStorage.add(taskResult);
it.remove();
taskCompleted++;
}
}
}
}
}
}
ThreadExecutorFactory.java
#Component
public class ThreadExecutorFactory {
private int THREAD_LIMIT = 100;
private final Executor executor;
public ThreadExecutorFactory() {
executor = Executors.newFixedThreadPool(THREAD_LIMIT,
new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
}
public Executor getExecutor() {
return executor;
}
}
Task.java
public abstract class Task<T extends TaskResult> implements Callable<T> {
}
TaskResult.java
public abstract class TaskResult {
}
Your method awaitForResults contains a busy loop:
while(taskCompleted < submittedTasks){
...
while(it.hasNext()){
This will eat CPU like crazy, and hinders the actual threads. You should either add a sleep like for instance
Thread.sleep(1000);
This is Quick&Dirty but will help solving the 100% cpu. Alternatively but more effort is to implement some signalling mechanism so the loop waits for a signal from one of the finished tasks.
Like others suggested, it likely doesn't make sense to have 100 threads if they're all cpu-bound, but I doubt that is really your problem.

Time out a java code?

I am writing an online java programming app where I take a java code as input from user and returns the output after compilation and execution through a python script.
For controlling the memory heap I have a standard solution of using -Xms and -Xmx while running the code in JVM. I have installed Sun Java 1.7.0_40.
Now the problem is that I am confused about how to restrict the code with a time limit. For example any code submitted by user in my app should not run for more than T seconds, where T is a variable.
I wrote one simple hack using Timer class but the problem is I have to use a lot of regex to inject it in the user code which I primarily want to avoid. As I am more comfortable in python and c++ than java as a programmer, I need some guidance about whether there exists some easy solution for such problem or what are the pros and cons of using the Timer class.
Any help will be much appreciated!
Thanks
I've done simple 'TimeoutThread' util using by ExecutorService.
2 classes:
package eu.wordnice.thread;
/*** Runa.java ***/
import java.util.concurrent.Callable;
public class Runa implements Callable<Object> {
private Runnable run = null;
public Runa(Runnable run) {
this.run = run;
}
public Runa(Thread run) {
this.run = run;
}
public Runa() {}
public Object call() throws Exception {
if(run != null) {
run.run();
}
return -1;
};
}
And:
package eu.wordnice.thread;
/*** TimeoutThread.java ***/
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class TimeoutThread {
public Runa run = null;
public ExecutorService executor = null;
public long timeout = 100L;
private boolean canceled = false;
private boolean runed = false;
public TimeoutThread(Runnable runit, long timeout) {
this(new Runa(runit), timeout);
}
public TimeoutThread(Runa runit, long timeout) {
this.run = runit;
if(timeout < 1L) {
timeout = 10L;
}
this.timeout = timeout;
}
public Object run() {
return this.run(false);
}
public Object run(Object defaulte) {
this.runed = true;
List<Future<Object>> list = null;
try {
this.executor = Executors.newCachedThreadPool();
list = executor.invokeAll(Arrays.asList(this.run), this.timeout, TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace();
this.canceled = true;
}
executor.shutdown();
if(list == null) {
return defaulte;
}
if(list.size() != 1) {
return defaulte;
}
try {
Future<Object> f = list.get(0);
try {
return f.get();
} catch (Exception e) {
this.canceled = true;
}
} catch (Exception e) { }
return defaulte;
}
public boolean wasRunned() {
return this.runed;
}
public boolean wasCanceled() {
return this.canceled;
}
}
Example:
public static void main(String... blah) {
TimeoutThread thr = new TimeoutThread(new Runa() {
#Override
public Object call() throws Exception {
while(true) {
System.out.println("Yeeee");
Thread.sleep(300L);
}
}
}, 500L);
thr.run();
}
Print:
Yeeee
Yeeee
EDIT!
Sorry, that is Timeout Runnable. If you want Timeout Tread, just put the code / call into Thread.
public static void main(String... blah) {
final TimeoutThread thr = new TimeoutThread(new Runa() {
#Override
public Object call() throws Exception {
while(true) {
System.out.println("Yeeee");
Thread.sleep(300L);
}
}
}, 500L);
new Thread() {
#Override
public void run() {
thr.run(); //Call it
}
}.start(); //Run it
}
I would have a look at using ExecutorService in Java for this and have the class with the functionality you want to time out implement runnable - so using Java's threading capabilities to help you out.
You should be able to timeout the thread using the following code:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
But you may need to check out the documentation a bit to get it to work for your use case.
See the following post for more advice on this kind of thing.
Not sure if you're wanting to have the timeout in your python code or in Java, but hopefully this'll help a bit.
You can use ThreadPoolExecutor
sample:
int corePoolSize = 5;
int maxPoolSize = 10;
long keepAliveTime = 5000;
ExecutorService threadPoolExecutor =
new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
keepAliveTime,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()
);
threadPoolExecutor.execute(new Runnable(){
#Override
public void run() {
// execution statements
});
References
http://tutorials.jenkov.com/java-util-concurrent/threadpoolexecutor.html

Categories

Resources