How to reuse ThreadPoolExecutor after shutdown - java

In my application i have used a custom ThreadPoolExecutor which enables pausing and resuming of the Executor by extending the ThreadPoolExecutor class. Same way I want to have Restart functionality implemented where after the shutdown method of the ExecutorService has been executed. I first tried with creating new instance of the ThreadPoolExecutor and it failed. I found this question and tried the ExecutorCompletionService which resulted the same failure where it didn't executed as intended.
First time when I click the start button in my UI it executes fine and after the completion of the process when I again start, it won't give me the intended result. Instead will give me the same previous result of the first run. What is the best suitable way which I can achieve this task ?
Thanks in advance :)
Following lines will be executed at each button click.
private static int jobs = 10;
ExecutorService executor = new PausableThreadPoolExecutor(num_threads, num_threads, 5000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(jobs));
for (int i = 0; i < jobs; i++) {
Runnable worker = new TaskToDo(jobs);
executor.submit(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {}
System.out.println("Finished all threads");
This is the source I used to have pause/resume implementation.

Maybe a ScheduledThreadPoolExecutor you can restart it ScheduledThreadPoolExecutor
using this the methods can return a ScheduledFuture ScheduledFuture or a Future Future to hold references to the tasks
ScheduledFuture now = null;
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1);
Runnable runner = new Runnable(){
public void run()
{
rollthedice(); //your method or runnable of choice
}
};
to start and restart something like "theres other methods too"
now = scheduler.scheduleAtFixedRate(runner, 0, 250, TimeUnit.MILLISECONDS);
to cancel or stop
now.cancel(true);
now = null;

Related

How to set max execution time on individual tasks running on threads?

I have a set of tasks in multiple levels that I need to run in parallel on threads taken from a thread pool.
I am using a countdown latch to time the overall execution of the level.
Problem: there are few tasks which get to execute more than their individual time just because of other tasks present in the same level that have more execution time. I want to avoid that.
Below is the code I'm using.
private final ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat(
"TaskExecutor-thread-%d").build());
....
for (int i = 0; i < levels.size(); i++) {
Set<AbstractTask> taskSet = levels.get(i);
CountDownLatch latch = new CountDownLatch(taskSet.size());
int maxAwaitTime = TaskExecutorHelper.getMaxAwaitTime(taskSet); //this returns max of all
// execution time set for
//individual tasks
for (AbstractTask t : taskSet) {
executor.submit(() -> { t.doExecute(input); });
}
latch.await(maxAwaitTime, TimeUnit.MILLISECONDS);
}
Any help would be appreciated!
A possible solution is to set a task that will interrupt execution after given timeout. The following example may give you an idea:
private final ExecutorService executor = ...;
private final ScheduledExecutorService scheduler = ...;
Future future = executor.submit(() -> ... );
ScheduledFuture scheduledFuture = scheduler.schedule(() -> future.cancel(true), 10, TimeUnit.SECONDS);
You will need some code to cancel timeout handler after task execution.
See ScheduledExecutorService#schelude for details.

Run ExecutorService tasks continuously

I want to use method newWorkStealingPool() to get thread and run them continuously every 1 sec. Using the following sample code :
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () -> System.out.println("Scheduling: " + System.currentTimeMillis());
int initialDelay = 0;
int period = 1;
executor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);
I can run task continuously but I want to use the method newWorkStealingPool() to get threads. Using the following code:
ScheduledExecutorService executor = (ScheduledExecutorService)Executors.newWorkStealingPool();
Runnable task = () -> System.out.println("Scheduling: " + System.currentTimeMillis());
int initialDelay = 0;
int period = 1;
executor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);
I got the error:
java.util.concurrent.ForkJoinPool cannot be cast to java.util.concurrent.ScheduledExecutorService
Using ExecutorService object it's possible to use newWorkStealingPool() but I don't know if is there any way to run ExecutorService object continuously like what object ScheduledExecutorService provides?
I think this can be achieved with creating ScheduledExecutorService and ForkJoinPool. ScheduledExecutorService will be used to submit tasks to ForkJoinPool at specified intervals. And ForkJoinPool will execute these tasks.
ForkJoinPool executor = (ForkJoinPool) Executors.newWorkStealingPool();
// this will be only used for submitting tasks, so one thread is enough
ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
Runnable task = () -> System.out.println("Scheduling: " + System.currentTimeMillis());
int initialDelay = 0;
int period = 1;
scheduledExecutor.scheduleAtFixedRate(()->executor.submit(task), initialDelay, period, TimeUnit.SECONDS);
The Executors.newWorkStealingPool() produces a ForkJoinPool. The ForkJoinPool class does not implement the ScheduledExecutorService interface so you cannot cast it to a ScheduledExecutorService.
Furthermore the ForkJoinPool and ScheduledExecutorService are fundamentally different thread pools. If you need to schedule a task to execute once every second stick with a ScheduledExecutorService, since it is suitable for your use case. ForkJoinPools are intended to use in cases where you have many small units of work divided among many threads, not for when you want to regularly execute something.

How do I write a Junit test for a ThreadPoolExecutor

How can I write a Junit test for the following function. ParallelExecutor extends ThreadPoolExecutor and the WorkerThread will call latch.countDown() on a value change(listener). WorkerThread is a 3 party class. Please let me know how I can tell the test to decrease the latch.
public static void OpenScreen() throws InterruptedException {
//some job...3 party screen
// creating the ThreadPoolExecutor
final ParallelExecutor executorPool = new ParallelExecutor(10);
final CountDownLatch latch = new CountDownLatch(0);
// start the monitoring thread
final MyMonitorThread monitor = new MyMonitorThread(executorPool, 3);
final Thread monitorThread = new Thread(monitor);
monitorThread.start();
// monitorThread.start();
// submit work to the thread pool
for (int i = 0; i < 10; i++) {
executorPool.execute(new WorkerThread(("cmd" + i), latch));
}
latch.await();
Thread.sleep(30000);
// shut down the pool
executorPool.shutdownNow();
// shut down the monitor thread
monitor.shutdown();
}
So what do you want to test? :-) That the execute methods are called? The counting works? Timeouting works if one of the tasks take too much to execute? All the jobs completed when the openScreen() method returns?
If you want to do unit tests, you can play around with mocks (for that, I'd extract this functionality to a separate class where the dependencies like the pool and monitor are passed/injected for the new class). There you can verify if the methods were called properly.

Executor Service and scheduleWithFixedDelay()

Here is my task. I have a static queue of jobs in a class and a static method that adds jobs to the queue. Have n amount of threads that poll from a queue and perform the pulled job. I need to have the n threads poll simultaneously at an interval. AKA, all 3 should poll every 5 seconds and look for jobs.
I have this:
public class Handler {
private static final Queue<Job> queue = new LinkedList<>();
public static void initialize(int maxThreads) { // maxThreads == 3
ScheduledExecutorService executorService =
Executors.newScheduledThreadPool(maxThreads);
executorService.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
Job job = null;
synchronized(queue) {
if(queue.size() > 0) {
job = queue.poll();
}
}
if(job != null) {
Log.log("start job");
doJob(job);
Log.log("end job");
}
}
}, 15, 5, TimeUnit.SECONDS);
}
}
I get this output when I add 4 tasks:
startjob
endjob
startjob
endjob
startjob
endjob
startjob
endjob
It is obvious that these threads perform that jobs serially, whereas I need them to be done 3 at a time. What am I doing wrong? Thanks!
From the documentation:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
So you must schedule three independent tasks to have them run concurrently. Also note that the scheduled executor service is a fixed thread pool, which is not flexible enough for many use cases. A good idiom is to use the scheduled service just to submit tasks to a regular executor service, which may be configured as a resizable thread pool.
You are running ScheduledExecutorService with fixed delay, what means, that your jobs will run one after one. Use fixed thread pool, and submit 3 threads at a time. Here is an explanation with examples
If you declare Job extends Runnable then your code simplifies dramatically:
First declare the Executor somewhere globally accessible:
public static final ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);
Then add a job like this:
executor.submit(new Job());
You are done.

Periodically running a Callable via ScheduledExecutorService

I have a Callable<String>. I want to run it periodically via ScheduledExecutorService.scheduleAtFixedRate(), and to get a list of all the Strings that were returned by the .call() invocations on my callable. As scheduleAtFixedRate does not take a Callable (only Runnables) I need to roll out a custom Runnable that wraps my Callable, something along these lines:
final Callable<String> myCallable = ....;
final ConcurrentLinkedQueue<String> results
= new ConcurrentLinkedQueue<String>();
Runnable r = new Runnable() {
#Override public void run() {
try {
results.add(myCallable.call());
} catch (Exception e) {
results.add(null); // Assuming I want to know that an invocation failed
}
}
};
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(r, 0, 1, TimeUnit.SECONDS);
Naturally, I'd like to avoid rolling out my own custom thingies (especially in multi-threaded code), so I wonder there is a JDK class that does this kind of aggregation?
What you are doing above is treating your Callable implementation as just another normal class. You are not submitting the callable to a ThreadPool executor. Calling Callable.call() doesn't utilize the ThreadPoolExecutor.
You need to submit your Task (Runnable/Callable/ForkJoinTask,etc..) to a ThreadPool to utilize the thread pooling.
You can use the Futures to collect the results once executed.
ForkJoinPool is one option you can try thats part of JDK 7. Fork the tasks and Join them using ForkJoinTask
Why not use Futures? They are exactly meant for knowing the state of Task and its result.
Did you look at this : Using Callable to Return Results From Runnables

Categories

Resources