How to use Future and Callable in my own thread pool implementation - java

I am trying to implement my own thread pool in Java (for didactic purposes).
In my thread pool class, I have this method:
public Future submit (Task task) { //(Task implements Callable<String>)
FutureTask<String> futureTask = new FutureTask<String>(task);
taskQueue.put(task); //It is a BlockingQueue
return futureTask;
}
I am wrapping my Task into a FutureTask, put it in a synchronized queue and immediately return the FutureTask.
When I am trying to add tasks to the pool, I do:
Future<String> futureTask = threadPool.submit(new Task(/*arguments*/));
//In theory, I could do something else here
String taskRes = futureTask.get();
I use the above code with some threads, but futureTask.get() never returns.
My threads do something like this:
public void run() {
Task task = taskQueue.take();
task.call();
}
Is there something logically wrong on how I used Future and Callable?
I mean a Task is wrapped into a FutureTask in one thread, but it is called in another one. For some reasons futureTask.get() can not get the return value of task.call().

Related

Can the number of tasks submitted to a thread pool be limited

I have a scenario that I have a thread pool with 100 threads for example.
There are 10 jobs, each of these jobs can send 1..n tasks to the thread pool.
If I just submit them directly, they will job compete for the threads in the pool.
Is there any way I can say something like:
Job 1 can submit a maximum of 5 tasks to the thread pool at the same time and have to wait for one of them to complete before sending the next one.
I know I can do this if I have separate thread pools for each job. But these jobs are incoming requests that appear and dissapear on the fly. It might not be good to dynamically create thread pools this way.
Can I achieve the above using one single big thread pool?
You can create your own ExecutorService, something like:
class LimitingExecutorService implements ExecutorService {
private final ExecutorService delegate;
private final Semaphore semaphore;
LimitingExecutorService(ExecutorService delegate, int limit) {
this.delegate = delegate;
this.semaphore = new Semaphore(limit);
}
Now, you can implement the methods to delegate the call to delegate, but checking that the semaphore can be acquired, e.g.:
public Future<?> submit(Runnable task) {
// Or you could block.
if (!semaphore.tryAcquire()) {
throw new RejectedExecutionException(...); // Indicate that the task couldn't be submitted.
}
// Wrap task with in another runnable() that releases the semaphore (whether or not it succeeds).
try {
return delegate.submit(() -> {
try {
task.run();
} finally {
semaphore.release();
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
etc for other methods.
You will need to take care around methods like invokeAll to decide what the behavior should be: should they invoke as many as they can, or should that call only succeed if all tasks can be scheduled at that moment.
Now, each of your jobs can have their own instance of LimitingExecutorService, and they can only submit as many jobs as the semaphore's available permits allow.

javafx get result from thread with callable

I have a javafx app, and I want to surround some code with "waiting" feature. So my code can be Runnable and Callable. The problem is getting result from Callabe. I tried to play with:
wait()/notify()
Platform.runLater
creating daemon threads by hands
Service
after reading some articles here, but it doesn't help.
How I want to call it:
final String a =
CommonHelper.showWaiting(() -> {
System.out.println("test");
return "test2";
});
That's how I work with Runnable:
public static void showWaiting(Runnable runnable) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
executorService.submit(new WaitingTask<>(executorService.submit(runnable)));
} finally {
executorService.shutdown();
}
}
And my WaitingTask is:
public class WaitingTask<T> extends Task<Void> {
#Getter
private final Future<T> future;
public WaitingTask(Future<T> future) {
this.future = future;
}
#Override
protected Void call() {
showSpinner();
while (true) {
if (future.isDone()) {
hideSpinner();
break;
}
}
}
return null;
}
}
That works awesome - my app shows waiting spinner, and task runns in separate thread.
So I try to work the same way with Callable to get the result:
public static <T> T showWaiting(Callable<T> callable) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
FutureTask<T> task = new FutureTask<>(callable);
Future<T> result = (Future<T>) executorService.submit(task);
executorService.submit(new WaitingTask<>(result));
return result.get();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
executorService.shutdown();
}
}
but I can not see waiting spinner, maybe the app's main thread waits for result.get(); and the app freezes. How can I fix it?
There are a few things you are doing incorrectly:
You wrap your Callable in a FutureTask before submitting it to an ExecutorService. You don't need to do this, and in fact you shouldn't do this. Instead, just submit your Callable directly and you will get a Future in return.
Future<T> future = executor.submit(callable);
If you're using the core implementation of ExecutorService the returned Future will be a FutureTask anyway. Not that you should care—the only important thing is that its a Future. Note the same goes for Runnables; just submit them directly, don't wrap them in a FutureTask first.
You're submitting your Callable, getting a Future, and wrapping said Future in a Task...and then submitting your Task. This means you will have two tasks for every one you want to execute. Depending on how your ExecutorService is configured, this equates to using two threads per task.
You should be using your Task as if it was your Callable. Do the work inside the Task#call() method and return the result. Then only submit the Task, don't wrap it in anything first.
executor.execute(task); // Don't need the Future here, just use "execute"
If you want the result of the Task you can register callbacks (see this). The class is designed to invoke these callbacks on the JavaFX Application Thread.
task.setOnSucceeded(event -> {
T value = task.getValue();
// do something with value...
});
Note that Task extends FutureTask. This seems contradictory to point 1, but that's just how it is. Personally, I wouldn't have designed the class that way—it ends up wrapping the Task in another Future (likely FutureTask) when executed using the Executor Framework.
This is related to number 2; if you fix that issue then this issue inherently goes away.
You are spin waiting for the wrapped Future to complete. This is a waste of resources. The Future interface has a get() method that will block the calling thread until said Future is done. If the Future completes normally you'll get the value in return, else if it completes exceptionally an ExecutionException will be thrown. The third option is the calling thread is interrupted and an InterruptedException is thrown.
If the method names "showSpinner" and "hideSpinner" aren't misleading, you are updating the UI from a background thread. Never update the UI from a thread other than the JavaFX Application Thread. Now, you could wrap those calls in a Platform.runLater action, but you could also use the properties/callbacks of the Task. For instance, you could listen to the running property to know when to show and hide your spinner.
Taking all that into account, your example should look more like:
// Doesn't have to be an anonymous class
Task<String> task = new Task<>() {
#Override
protected String call() {
System.out.println("test");
return "test2";
}
});
task.runningProperty().addListener((obs, wasRunning, isRunning) -> {
if (isRunning) {
showSpinner();
} else {
hideSpinner();
}
});
task.setOnSucceeded(event -> {
String a = task.getValue();
// Do something with value.
});
executorService.execute(task);
For more information, I suggest reading:
Concurrency in JavaFX
Documentation of javafx.concurrent.Worker
Documentation of javafx.concurrent.Task (and Worker's other implementations)
Possibly a tutorial on Java's Executor Framework.
Thanks all for help, especially #Slaw and #kendavidson
Finally I've found a simple and perfect solution here:
Modal JaxaFX Progress Indicator running in Background
Maybe I'll post my full generic-based example here, based on this principles

How can I tell that threads in ThreadPoolExecutor are done?

I am writing code where I need to make sure that no threads are currently running in a thread pool before I commit results (to avoid losing data I should have put in the commit). For that, I'm using:
while (_executor.getActiveCount() > 0)
{
try
{
Thread.sleep(10); // milliseconds
}
catch (InterruptedException e)
{
// OK do nothing
}
}
But a colleague pointed out in review that the doc for getActiveCount states:
Returns the approximate number of threads that are actively
executing tasks.
So, is there a risk I would get out of the while loop while there are still active threads in the pool? If so, what would be the correct way to wait for all my worker threads to be done?
Edit: To give some more context: this is an online system, where the task that contains the executor service is left running indefinitely. Work comes in via a messaging system, is put on a thread in the executor, which doesn't need any synchronization, and works come out into another queue for the messaging system. I don't want to kill the executor to wait for completion of tasks.
You might want to consider using a CompletionService (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CompletionService.html).
A CompletionService wraps an ExecutorService and returns a Future when tasks are submitted. By maintaining a list of these Futures, you can see if the jobs that you're waiting on have completed. It also has the additional advantage that you can have others use the same ExecutorService since you have some means of accounting,
_executor.awaitTermination(); should do the job. Now, it won't actually wait for the threads to shutdown, but rather it would wait for all available tasks to terminate.
You could also provide keepAliveTime to a thread pool constructor to instantly terminate idle threads:
ExecutorService executor = new ThreadPoolExecutor(0, 10, 0L /* keepAlive */,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
To notify a thread that it should clean up and terminate, use the interrupt method.
t.interrupt();
and it is good to print or have log of your errors from catch block.
When tasks are submitted to the executor, they return Futures, which indicate when they complete. That is the preferred mechanism to use.
You can use JDK ExecutorService shutdown/awaitTermination.
Use case: need to cleanup thread-locals in pool threads upon their completion and this cleanup can take long (e.g. connection close). Only after that the main thread can continue.
A worker thread can register itself in some collection. For that override start() and run() and pass a custom thread factory to ThreadPoolExecutor:
class MyThreadFactory implements ThreadFactory {
#Override
public Thread newThread(final Runnable r) {
return new MyThread(r);
}
...
class Some {
void waitAllThreads() {
Thread worker;
while ((worker = workerThreads.poll()) != null) {
worker.join();
}
}
...
class MyThread extends Thread {
#Override
public synchronized void start() {
if (getState() == State.NEW) {
some.workerThreads.offer(this);
}
super.start();
}
#Override
public void run() {
try {
super.run();
} finally {
some.workerThreads.remove(this);
}
}
...

executor cancel pending task - help needed

Basically, I need a machinery to have the following:
Fixed-sized thread pool to run tasks
Queue of pending tasks (requested, but not yet running)
Cancelling task in pending queue (task is identified by id)
Cancelling ongoing task
Given task id, query whether task is Pending or Running
Could anyone suggest best way of achieving this, especially items 3-5. I would really appreciate some code example.
Thanks.
Everything but task states and cancelling is standard for thread pools. Cancellations and status state could be done the following way:
enum TaskState {PENDING, RUNNING};
abstract class MyCallable<V> implements Callable<V>{
protected volatile TaskState state = PENDING;
// to make sure state is always set before running the task
protected abstract V doCall();
final V call(){
state = RUNNING;
return doCall();
}
public TaskState getState() { return state; }
}
...
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<V> future = executor.submit(new MyCallable<V>() {
public V doCall() throws Exception {
//... some work ...
if(Thread.interrupted()){
removeFromMap();
return null;
}
}
});
...
future.cancel(true);
To make task cancellable one needs to check Thread.interrupted() state during it's execution or some other logical boolean flag. After getting a future for the submitted task, future.cancel(true) should be called to cancel the task by interrupting it.
Everything you need is in the tags. If you use a fixed thread pool ExecutorService, you can limit the number of threads that can execute simultaneously.
If more threads are submitted than can be handled, they are held in a queue.
Calling the submit() method of an ExecutorService will give you a Future object which will let you know whether the task is pending or it has been cancelled, etc
I do have a series of tutorials on ExecutorService: http://codelatte.wordpress.com/2013/11/09/a-simple-newfixedthreadpool-example/
How to use Future object: http://codelatte.wordpress.com/2013/11/08/a-simple-cachedthreadpool-example/

Could I join threads in a better way?

Suppose I have multiple Runnable instances in a program, all dispatched by an Executor instance. Further, suppose I at some point need to wait for a subset of these runnables to finish before moving on.
One way I could do this is the following:
public abstract class Joinable implements Runnable {
private final Semaphore finishedLock = new Semaphore(1);
#Override
public final void run() {
try {
finishedLock.acquireUninterruptibly();
doWork();
} finally {
finishedLock.release();
}
}
public abstract void doWork();
public void join() {
finishedLock.acquireUninterruptibly();
}
}
Implementing classes can then simply override doWork(), rather than run(), in order to define what should be done during execution.
The joining process will then simply look like this:
void doStuff() {
Executor executor = Executors.newCachedThreadPool();
List<Joinable> joinables = new LinkedList<Joinable>();
// Fill joinables with implementors of Joinable...
List<Runnable> others = new LinkedList<Runnable>();
// Fill others with implementors of Runnable...
for(Joinable joinable : joinables)
executor.execute(joinable);
for(Runnable runnable : others)
executor.execute(runnable);
for(Joinable joinable : joinables)
joinable.join();
// Continue, no matter what the threads in others are up to.
}
Is this a good way to solve this problem (is it even safe?), or is there a better one?
Your current solution is not thread safe. There are no guarantees that the executor will call run on your Joinable before you call join. Thus, in certain cases, your main thread will acquire the lock before your Joinable does.
On possible solution would be instead to use a CountDownLatch if you know the total number of joinables N, you create a CountDownLatch(N) and pass it to each instance. When each joinable is finished, have it call countDown(). Your main thread calls await() on the latch. await() doesn't return until the latch count is 0.
Is this a good way to solve this problem (is it even safe?)
This is not quite right. You can't join on a Runnable that you are executing by the ExecutorService. If you want to use a list then do something like this:
List<Future<?>> futures = new ArrayList<Future<?>>();
for(Joinable joinable : joinables) {
// this submit returns a `Future`.
futures.add(executor.submit(joinable));
}
// submit others to the executor _without_ adding to the futures list
for (Future<?> future : futures) {
// this can throw ExecutionException which wraps exception thrown by task
future.get();
}
or is there a better one?
If you were waiting for all tasks to complete then you could use the ExecutorService.awaitTermination(long timeout, TimeUnit unit) method. For example:
executor.awaitTerminate(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
But I don't see any better way to do this if you are waiting for a subset of tasks.

Categories