Periodically running a Callable via ScheduledExecutorService - java

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

Related

JavaFX Task Callable

I was developing a JavaFX app and I was supplying the JavaFX tasks in an ExecutorService submit method. Also I was trying to get the return value of the Task in the return value of the submit in a Future object. Then I discovered that ExecutorService only returns value when you submit a Callable object, and JavaFX Tasks are runnables despite having a call method. so is there any workaround for this problem?
I tried and solved my problem this way but I'm open to suggestions when I don't want to write my own class.
My main method:
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Semaphore semaphore = new Semaphore(1);
List<Integer> list = IntStream.range(0,100).boxed().collect(Collectors.toList());
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
List<Integer> sendingList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
sendingList.add(iterator.next());
}
System.out.println("SUBMITTING");
Future<Integer> future = executorService.submit((Callable<Integer>) new TestCallable(sendingList,semaphore));
System.out.println(future.get());
semaphore.acquire();
}
executorService.shutdown();
System.out.println("COMPLETED");
}
My TestCallable class:
class TestCallable extends Task<Integer> implements Callable<Integer> {
private Random random = new Random();
private List<Integer> list;
private Semaphore semaphore;
TestCallable(List<Integer> list, Semaphore semaphore) {
this.list = list;
this.semaphore = semaphore;
}
#Override
public Integer call(){
System.out.println("SENDING");
System.out.println(list);
try {
Thread.sleep(1000+random.nextInt(500));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("RECEIVED");
semaphore.release();
return list.size();
}
}
Task extends java.util.concurrent.FutureTask which in turn implements the Future interface. This means you can use a Task just like a Future.
Executor executor = ...;
Task<?> task = ...;
executor.execute(task);
task.get(); // Future method
This will cause the thread calling get() to wait until completion. However, a Task's purpose is to communicate the progress of a background process with the JavaFX Application Thread. It's close relationship to the GUI means you will most likely be launching a Task from the FX thread. This will lead to get() being called on the FX thread which is not what you want as it will freeze the GUI until get() returns; you might as well have just called Task.run directly.
Instead, you should be using the asynchronous functionality provided by Task. If you want to retrieve the value when the Task completes successfully you can use the onSucceeded property or listen to the value/state property. There's also ways to listen for failure/cancellation.
Executor executor = ...;
Task<?> task = ...;
task.setOnSucceeded(event -> handleResult(task.getValue()));
task.setOnFailed(event -> handleException(task.getException()));
executor.execute(task);
If you don't need the functionality provided by Task then it would probably be best to simply use Runnable or Callable directly.
It's not very clear what you want to do here.
Firstly, your Semaphore does nothing because you used Executors.newSingleThreadExecutor(), which already guarantees that only one task can run at any point in time.
Secondly, like what #Slaw mentioned, you are potentially blocking on JavaFX Application thread, depending on your actual implementation (your example isn't really a JavaFX application).
Next, ExecutorService has 2 main overloads for submit().
The first overload takes in a Callable. This overload allows you to retrieve the value returned by the Callable (by calling get() on the returned Future), because Callable refers to something that is can be called - it can return value.
The second overload takes in a Runnable. Since Task implements Future RunnableFuture interface, and Future RunnableFuture interface extends Runnable interface, passing in a Task would be equivalent to calling this overload. This overload does not expect a result to be returned, because Runnable is something that you run without a result. Calling get() on the Future returned by this overload will block until the task finishes, and null will be returned. If you need to retrieve the value returned by the Task, you need to call get() of the Task, not the Future returned by ExecutorService.submit().
Edit based on OP's comments
Firstly, since the calling method is already running in a background thread, and all tasks are expected to run sequentially (instead of parallelly), then you should just run them without all these additional ExecutorService and Task, unless there is another reason why this has to be done.
Secondly, a List object is nothing but an object doing referencing. What could have really affected performance is that you are copying the reference of the elements to the new list. You could have used List.subList()if the indices are known, as the returned list would use the same backing array as the original list, so there isn't an additional O(n) operation for copying.

Control Multithreading in Java

I have one "Runnable" threads which is initiating few "Callable" threads and I want to display results when all above threads has finished their jobs.
What is the best way to do it?
My code is as follows
Connector.java (Starting Runnable Thread)
public class Connector {
private static void anyFileConnector() {
// Starting searching Thread
ExecutorService executor = Executors.newFixedThreadPool(100);
executor.submit(traverse, executor);
//HERE I WANT MY ALL SEARCH RESULTS/OUTPUT : CURRENTLY IT IS STARTING OTHER THREADS AND NOT SHOWING ME ANY RESULTS BECAUSE NONE OF THEM WAS FINISHED.(IN CONSOLE, I WAS ABLE TO SEE RESULTS FROM ALL THE THREADS
setSearchResult(traverse.getResult());
executor.shutdown();
}
}
Traverse.java (Runnable Thread)
I am using ExecutorCompletionService to handle it...but it didn't create any difference.
:(
public class Traverse implements Runnable {
public void run() {
ExecutorService executor = Executors.newFixedThreadPool(100);
ExecutorCompletionService<List<ResultBean>> taskCompletionService =
new ExecutorCompletionService<List<ResultBean>>(executor);
try (DirectoryStream<Path> stream = Files
.newDirectoryStream(dir)) {
Search newSearch = new Search();
taskCompletionService.submit(newSearch);
}
list.addAll(taskCompletionService.take().get());
}
}
Search.java (Callable Thread)
public class Search implements Callable<List<ResultBean>> {
public List<ResultBean> call() {
synchronized (Search.class) {
// It will return results
return this.search();
}
}
}
Go for CyclicBarrier and you will be able to achieve this.
A cyclic barrier will perform a task as soon as all the threads are done with their work, this is where you can print the en result.
Check this lik for working of CyclicBarrier : http://javarevisited.blogspot.com/2012/07/cyclicbarrier-example-java-5-concurrency-tutorial.html
Easy - all the Callables will return Future objects which you can used to wait and get the result by calling Future.get() in a blocking wait way. So your problem is just a for loop waiting for each future on the callables blockingly.
After that, just aggregate the results to return to client.
The submit method of executor service can return a list of Future objects. What you can do for your case is call isDone() method of these Future objects in a while loop.
Whenever, any future task gets completed this method will return true. You can now call get() method on this to get the value returned by this task. In this way you could get hold of all the future task values without having to wait for any particular task to get complete (since your first future task could have the longest completion time)

Keep track of tasks submitted to ThreadPoolExecutor

I am running several tasks in a ThreadPoolExecutor. I initialise it as follows:
private VideoExportExecutor executor;
private BlockingQueue<Runnable> jobQueue;
public void initialiseVideoProcessor()
{
jobQueue = new LinkedBlockingQueue<Runnable>();
executor = new VideoExportExecutor(1, 1, Long.MAX_VALUE, TimeUnit.SECONDS, jobQueue);
}
I have made my own implementation of runnable (VideoExportThread) which contains a getProgress() method to keep track of the progress of submitted tasks. I submit instances of this as follows:
executor.submit(new VideoExportThread(gcmPath));
I am after a way to query the executor/blockingQueue for current/pending threads. I have tried to use jobQueue.toArray() and to override the executor method beforeExecute(Thread t, Runnable r) but in both cases the returned runnable is of type FutureTask which does not contain much data. Is there a way for me to use it to retrieve my original VideoExportThread instance in order to identify which ones are running and to query its progress?
Thanks
Why not simply keep a list of your Runnables?
List<Runnable> runnables = new ArrayList<> ();
VideoExportThread r = new VideoExportThread(gcmPath);
runnables.add(r);
executor.submit(r);
Also note that executor.submit(r); returns a Future - you can call its isDone() method to check if the submitted task is still running.
Side comment: there might be a good reason to manage the job queue manually, but if not, you use one of the factory methods to make your life easier. For example: ExecutorService executor = Executors.newCachedThreadPool();.

How to implement an ExecutorService to execute batches of tasks

I am looking for a way to execute batches of tasks in java. The idea is to have an ExecutorService based on a thread pool that will allow me to spread a set of Callable among different threads from a main thread. This class should provide a waitForCompletion method that will put the main thread to sleep until all tasks are executed. Then the main thread should be awaken, and it will perform some operations and resubmit a set of tasks.
This process will be repeated numerous times, so I would like to use ExecutorService.shutdown as this would require to create multiple instances of ExecutorService.
Currently I have implemented it in the following way using a AtomicInteger, and a Lock/Condition:
public class BatchThreadPoolExecutor extends ThreadPoolExecutor {
private final AtomicInteger mActiveCount;
private final Lock mLock;
private final Condition mCondition;
public <C extends Callable<V>, V> Map<C, Future<V>> submitBatch(Collection<C> batch){
...
for(C task : batch){
submit(task);
mActiveCount.incrementAndGet();
}
}
#Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
mLock.lock();
if (mActiveCount.decrementAndGet() == 0) {
mCondition.signalAll();
}
mLock.unlock();
}
public void awaitBatchCompletion() throws InterruptedException {
...
// Lock and wait until there is no active task
mLock.lock();
while (mActiveCount.get() > 0) {
try {
mCondition.await();
} catch (InterruptedException e) {
mLock.unlock();
throw e;
}
}
mLock.unlock();
}
}
Please not that I will not necessarily submit all the tasks from the batch at once, therefore CountDownLatch does not seem to be an option.
Is this a valid way to do it? Is there a more efficient/elegant way to implement that?
Thanks
I think the ExecutorService itself will be able to perform your requirements.
Call invokeAll([...]) and iterate over all of your Tasks. All Tasks are finished, if you can iterate through all Futures.
As the other answers point out, there doesn't seem to be any part of your use case that requires a custom ExecutorService.
It seems to me that all you need to do is submit a batch, wait for them all to finish while ignoring interrupts on the main thread, then submit another batch perhaps based on the results of the first batch. I believe this is just a matter of:
ExecutorService service = ...;
Collection<Future> futures = new HashSet<Future>();
for (Callable callable : tasks) {
Future future = service.submit(callable);
futures.add(future);
}
for(Future future : futures) {
try {
future.get();
} catch (InterruptedException e) {
// Figure out if the interruption means we should stop.
}
}
// Use the results of futures to figure out a new batch of tasks.
// Repeat the process with the same ExecutorService.
I agree with #ckuetbach that the default Java Executors should provide you with all of the functionality you need to execute a "batch" of jobs.
If I were you I would just submit a bunch of jobs, wait for them to finish with the ExecutorService.awaitTermination() and then just start up a new ExecutorService. Doing this to save on "thread creations" is premature optimization unless you are doing this 100s of times a second or something.
If you really are stuck on using the same ExecutorService for each of the batches then you can allocate a ThreadPoolExecutor yourself, and be in a loop looking at ThreadPoolExecutor.getActiveCount(). Something like:
BlockingQueue jobQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(NUM_THREADS, NUM_THREADS,
0L, TimeUnit.MILLISECONDS, jobQueue);
// submit your batch of jobs ...
// need to wait a bit for the jobs to start
Thread.sleep(100);
while (executor.getActiveCount() > 0 && jobQueue.size() > 0) {
// to slow the spin
Thread.sleep(1000);
}
// continue on to submit the next batch

How to manage M threads (1 per task) ensuring only N threads at the same time. With N < M. In Java

I have a queue of task in java. This queue is in a table in the DB.
I need to:
1 thread per task only
No more than N threads running at the same time. This is because the threads have DB interaction and I don't want have a bunch of DB connections opened.
I think I could do something like:
final Semaphore semaphore = new Semaphore(N);
while (isOnJob) {
List<JobTask> tasks = getJobTasks();
if (!tasks.isEmpty()) {
final CountDownLatch cdl = new CountDownLatch(tasks.size());
for (final JobTask task : tasks) {
Thread tr = new Thread(new Runnable() {
#Override
public void run() {
semaphore.acquire();
task.doWork();
semaphore.release();
cdl.countDown();
}
});
}
cdl.await();
}
}
I know that an ExecutorService class exists, but I'm not sure if it I can use it for this.
So, do you think that this is the best way to do this? Or could you clarify me how the ExecutorService works in order to solve this?
final solution:
I think the best solution is something like:
while (isOnJob) {
ExecutorService executor = Executors.newFixedThreadPool(N);
List<JobTask> tasks = getJobTasks();
if (!tasks.isEmpty()) {
for (final JobTask task : tasks) {
executor.submit(new Runnable() {
#Override
public void run() {
task.doWork();
}
});
}
}
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
}
Thanks a lot for the awnsers. BTW I am using a connection pool, but the queries to the DB are very heavy and I don't want to have uncontrolled number of task at the same time.
You can indeed use an ExecutorService. For instance, create a new fixed thread pool using the newFixedThreadPool method. This way, besides caching threads, you also guarantee that no more than n threads are running at the same time.
Something along these lines:
private static final ExecutorService executor = Executors.newFixedThreadPool(N);
// ...
while (isOnJob) {
List<JobTask> tasks = getJobTasks();
if (!tasks.isEmpty()) {
List<Future<?>> futures = new ArrayList<Future<?>>();
for (final JobTask task : tasks) {
Future<?> future = executor.submit(new Runnable() {
#Override
public void run() {
task.doWork();
}
});
futures.add(future);
}
// you no longer need to use await
for (Future<?> fut : futures) {
fut.get();
}
}
}
Note that you no longer need to use the latch, as get will wait for the computation to complete, if necessary.
I agree with JG that ExecutorService is the way to go... but I think you're both making it more complicated than it needs to be.
Rather than creating a large number of threads (1 per task) why not just create a fixed sized thread pool (with Executors.newFixedThreadPool(N)) and submit all the tasks to it? No need for a semaphore or anything like that - just submit the jobs to the thread pool as you get them, and the thread pool will handle them with up to N threads at a time.
If you aren't going to use more than N threads at a time, why would you want to create them?
Use a ThreadPoolExecutor instance with an unbound queue and fixed maximum size of Threads, e.g. Executors.newFixedThreadPool(N). This will accept a large number of tasks but will only execute N of them concurrently.
If you choose a bounded queue instead (with a capacity of N) the Executor will reject the execution of the task (how exactly depends on the Policy you can configure when working with ThreadPoolExecutor directly, instead of using the Executors factory - see RejectedExecutionHandler).
If you need "real" congestion control you should setup a bound BlockingQueue with a capacity of N. Fetch the tasks you want done from the database and put them into the queue - if it's full the calling thread will block. In another thread (perhaps also started using the Executor API) you take tasks from the BlockingQueue and submit them to the Executor. If the BlockingQueue is empty the calling thread will also block. To signal that you're done use a "special" object (e.g. a singleton which marks the last/final item in the queue).
Achieving good performance also depends on the kind of work that needs to be done in the threads. If your DB is the bottleneck in processing I would start paying attention to how your threads access the DB. Using a connection pool is probably in order. This might help you to achive more throughput, since worker threads can re-use DB connections from the pool.

Categories

Resources