I have the following test code.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
class MyTask extends FutureTask<String>{
#Override
protected void done() {
System.out.println("Done");
}
public MyTask(Runnable runnable) {
super(runnable,null);
}
}
public class FutureTaskTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
FutureTask<String> future = new MyTask(new Runnable() {
public void run() {
System.out.println("Running");
}
});
executor.submit(future);
try {
future.get();
} catch (Exception ex ) {
ex.printStackTrace();
}
executor.shutdownNow();
}
}
This works fine - the overridden 'done' methond in MyTask is called when the task is done.
But how does the executor know how to call that ?
The executor only have these submit methods:
public <T> Future<T> submit(Callable<T> task);
public Future<?> submit(Runnable task);
Internally it seems 'submit' wraps the callable/runnable in a new FutureTask().
As far as the executor is concerned I've submitted a Runnable or Callable - from what I gather from these 2 signatures.
How does it know I submitted a FutureTask and know how to call my overridden done() ?
From the executor's point of view, you've submitted a Runnable task. The run method of this task (implemented by FutureTask) is what calls done at the appropriate time. The executor doesn't make any direct call to done.
The executor doesn't call done(). done() gets called by FutureTask when the call to run() is complete.
Related
I create a Callable which should make a syncExec call. I delegate the Callable to a subclass of RecursiveTask (ForkJoinPool) which executes the call method of the Callable. The problem is that the code inside the run method is never reached. Do you know why and how to fix that?
public class someClass{
public static void main (String[] args){
Callable<Object> c = new Callable<Object>() {
#Override
public Object call() throws Exception {
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
#Override
public void run() {
System.out.println("hi");
}
});
return null;
}
});
ATLockTask task = new ATLockTask();
task.setCallable(c);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(task);
}
}
public class ATLockTask extends RecursiveTask<Object[]>{
Callable callable;
#Override
protected Object[] compute() {
try {
callable.call();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
ForkJoinPool.invoke blocks the current thread until the given task has completed. Display.syncExec waits until the SWT UI thread executes Display.readAndDispatch so it will wait forever because ForkJoinPool.invoke is blocking the UI thread.
Use ForkJoinPool.execute to start the task without blocking and the code works.
ScheduledThreadPoolExecutor (which implements ScheduledExecutorService) seems to be only running the SwingWorker class once when using the ScheduleAtFixedRate method. The original code is kinda long, so I made a new code that produces the same results below.
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class ScheduledThreadPoolExecutorTest extends SwingWorker<Void, Void>{
#Override
protected Void doInBackground() {
System.out.println("Yay!");
return null;
}
#Override
protected void done() {
try {
get();
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("Woohoo!");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleAtFixedRate(new ScheduledThreadPoolExecutorTest(), 0, 30, TimeUnit.MILLISECONDS);
}
});
}
}
This yields the results:
Yay!
Woohoo!
Why is ScheduledThreadPoolExecutor running SwingWorker only once? And what can I do to make the SwingWorker run every 30 milliseconds as indicated in the code?
While SwingWorker does implement the Runnable interface, per its API section on the doInBackground() method:
Note that this method is executed only once.
So while its inner run() method may repeatedly run, the doInBackground() will only run once. Not only that, but the run() method is marked final within SwingWorker, and so you can't override it to call doInBackground multiple times.
A better solution is not use a SwingWorker at all but rather a simpler Runnable-derived class.
SwingWorker extends Runnable, however, it uses FutureTask to run its computation.
From the javadoc:
A cancellable asynchronous computation. This class provides a base
implementation of {#link Future}, with methods to start and cancel
a computation, query to see if the computation is complete, and
retrieve the result of the computation. The result can only be
retrieved when the computation has completed; the {#code get}
methods will block if the computation has not yet completed. Once
the computation has completed, the computation cannot be restarted
or cancelled (unless the computation is invoked using
{#link #runAndReset}).
That is, the FutureTask will run only once, if you try to run it again, it will simply return.
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
There are two approaches to submitting and polling task for result
FutureTask futureTask = new FutureTask<String>(callable);
Use combination of Callable and Future and submit on ExecutorService. Retrieve result using future.get().
Future future = service.submit(callable);
Use FutureTask. This will wrap Callable and then retrieve result using FutureTask.
service.execute(task);
What is the advantage of using FutureTask over Callable + Future combination ?
Almost certainly none at all. A quick browse on GrepCode of the AbstractExecutorService shows each of these methods are simply helper methods that ultimately wrap the Callable/Runnable in a Future for you.
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
public Future<?> submit(Runnable task) {
// ...
RunnableFuture<Object> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
// ...
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
// ...
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
Using Future we can find out the status of the Callable task and get the returned Object. It provides get() method that can wait for the Callable to finish and then return the result.
Future provides cancel() method to cancel the associated Callable task. There is an overloaded version of get() method where we can specify the time to wait for the result, it’s useful to avoid current thread getting blocked for longer time. There are isDone() and isCancelled() methods to find out the current status of associated Callable task.
Here is a simple example of Callable task that returns the name of thread executing the task after one second. We are using Executor framework to execute 100 tasks in parallel and use Future to get the result of the submitted tasks.
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MyCallable implements Callable<String> {
#Override
public String call() throws Exception {
Thread.sleep(1000);
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
public static void main(String args[]){
//Get ExecutorService from Executors utility class, thread pool size is 10
ExecutorService executor = Executors.newFixedThreadPool(10);
//create a list to hold the Future object associated with Callable
List<Future<String>> list = new ArrayList<Future<String>>();
//Create MyCallable instance
Callable<String> callable = new MyCallable();
for(int i=0; i< 100; i++){
//submit Callable tasks to be executed by thread pool
Future<String> future = executor.submit(callable);
//add Future to the list, we can get return value using Future
list.add(future);
}
for(Future<String> fut : list){
try {
//print the return value of Future, notice the output delay in console
// because Future.get() waits for task to get completed
System.out.println(new Date()+ "::"+fut.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
//shut down the executor service now
executor.shutdown();
}
}
Where as FutureTask is base concrete implementation of Future interface and provides asynchronous processing. It contains the methods to start and cancel a task and also methods that can return the state of the FutureTask as whether it’s completed or cancelled. We need a callable object to create a future task and then we can use Java Thread Pool Executor to process these asynchronously.
Let’s see the example of FutureTask with a simple program.
Since FutureTask requires a callable object, we will create a simple Callable implementation.
public class MyCallable implements Callable<String> {
private long waitTime;
public MyCallable(int timeInMillis){
this.waitTime=timeInMillis;
}
#Override
public String call() throws Exception {
Thread.sleep(waitTime);
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class FutureTaskExample {
public static void main(String[] args) {
MyCallable callable1 = new MyCallable(1000);
MyCallable callable2 = new MyCallable(2000);
FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(futureTask1);
executor.execute(futureTask2);
while (true) {
try {
if(futureTask1.isDone() && futureTask2.isDone()){
System.out.println("Done");
//shut down executor service
executor.shutdown();
return;
}
if(!futureTask1.isDone()){
//wait indefinitely for future task to complete
System.out.println("FutureTask1 output="+futureTask1.get());
}
System.out.println("Waiting for FutureTask2 to complete");
String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);
if(s !=null){
System.out.println("FutureTask2 output="+s);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}catch(TimeoutException e){
//do nothing
}
}
}
}
FutureTask<T> class contains an additional " done()" method so we can override the done() method, then add the FutureTask object to the ExecutorService, so the done() method will invoke when the FutureTask completed immediately.
Listed below is example code that I found for using the java.util.concurrent.ExecutorService. The main class includes a shutdown() method that calls the shutdown() method on the ExecutorService. What I do not understand from this example is when this method would be invoked.
Thanks.
package multithreadingexample;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MultithreadingExample {
ExecutorService executor = Executors.newFixedThreadPool(3);
public void start() throws IOException {
int i=0;
while (!executor.isShutdown())
executor.submit(new MyThread(i++));
}
public void shutdown() throws InterruptedException {
executor.shutdown();
executor.awaitTermination(30, TimeUnit.SECONDS);
executor.shutdownNow();
}
public static void main(String argv[]) throws Exception {
new MultithreadingExample().start();
}
}
class MyThread implements Runnable {
private final int i;
MyThread(int i) {
this.i = i;
}
#Override
public void run() {
System.out.println("I am in thread:"+i);
}
}
Why it is there:
To provide a way to shut down the ExecutorService to stop it from running tasks and to free the threads that it is using.
How it gets called:
You need to call it when you are done using the ExecutorService. In the example code you provided it is not called anywhere.
From the documentation:
The shutdown() method will allow previously submitted tasks to execute
before terminating, while the shutdownNow() method prevents waiting
tasks from starting and attempts to stop currently executing tasks.
Lets have one classic Executor in application. Many parts of application use this executor for some computations, each computation can be cancelled, for this I can call shutdown() or shutdownNow() on Executor.
But I want to shutdown only part of tasks in Executor. Sadly I can't have access to Future objects, they are private part of computation implementation (actually computation is backed by actor framework jetlang)
I want something like Executor wrapper, which I could pass to computation and which should be backed by real Executor. Something like this:
// main application executor
Executor applicationExecutor = Executors.newCachedThreadPool();
// starting computation
Executor computationExecutor = new ExecutorWrapper(applicationExecutor);
Computation computation = new Computation(computationExecutor);
computation.start();
// cancelling computation
computation.cancel();
// shutting down only computation tasks
computationExecutor.shutdown();
// applicationExecutor remains running and happy
Or any other idea?
For those, who wants good ends: there is final solution, partially based of Ivan Sopov's answer. Luckily jetlang uses for running its tasks only Executor interface (not ExecutorService), so I make wrapper class which supports stopping tasks created only by this wrapper.
static class StoppableExecutor implements Executor {
final ExecutorService executor;
final List<Future<?>> futures = Lists.newArrayList();
boolean stopped;
public StoppableExecutor(ExecutorService executor) {
this.executor = executor;
}
void stop() {
this.stopped = true;
synchronized (futures) {
for (Iterator<Future<?>> iterator = futures.iterator(); iterator.hasNext();) {
Future<?> future = iterator.next();
if (!future.isDone() && !future.isCancelled()) {
System.out.println(future.cancel(true));
}
}
futures.clear();
}
}
#Override
public void execute(Runnable command) {
if (!stopped) {
synchronized (futures) {
Future<?> newFuture = executor.submit(command);
for (Iterator<Future<?>> iterator = futures.iterator(); iterator.hasNext();) {
Future<?> future = iterator.next();
if (future.isDone() || future.isCancelled())
iterator.remove();
}
futures.add(newFuture);
}
}
}
}
Using this is pretty straightforward:
ExecutorService service = Executors.newFixedThreadPool(5);
StoppableExecutor executor = new StoppableExecutor(service);
// doing some actor stuff with executor instance
PoolFiberFactory factory = new PoolFiberFactory(executor);
// stopping tasks only created on executor instance
// executor service is happily running other tasks
executor.stop();
That's all. Works nice.
How about having your Computation be a Runnable (and run using the provided Executor) until a boolean flag is set? Something along the lines of :
public class Computation
{
boolean volatile stopped;
public void run(){
while(!stopped){
//do magic
}
public void cancel)(){stopped=true;}
}
What you are doing is essentially stopping the thread. However, it does not get garbage-collected, but is instead re-used because it is managed by the Executor. Look up "what is the proper way to stop a thread?".
EDIT: please note the code above is quite primitive in the sense it assumes the body of the while loop takes a short amount of time. If it does not, the check will be executed infrequently and you will notice a delay between canceling a task and it actually stopping.
Something like this?
You may do partial shutdown:
for (Future<?> future : %ExecutorServiceWrapperInstance%.getFutures()) {
if (%CONDITION%) {
future.cancel(true);
}
}
Here is the code:
package com.sopovs.moradanen;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ExecutorServiceWrapper implements ExecutorService {
private final ExecutorService realService;
private List<Future<?>> futures = new ArrayList<Future<?>>();
public ExecutorServiceWrapper(ExecutorService realService) {
this.realService = realService;
}
#Override
public void execute(Runnable command) {
realService.execute(command);
}
#Override
public void shutdown() {
realService.shutdown();
}
#Override
public List<Runnable> shutdownNow() {
return realService.shutdownNow();
}
#Override
public boolean isShutdown() {
return realService.isShutdown();
}
#Override
public boolean isTerminated() {
return realService.isTerminated();
}
#Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return realService.awaitTermination(timeout, unit);
}
#Override
public <T> Future<T> submit(Callable<T> task) {
Future<T> future = realService.submit(task);
synchronized (this) {
futures.add(future);
}
return future;
}
public synchronized List<Future<?>> getFutures() {
return Collections.unmodifiableList(futures);
}
#Override
public <T> Future<T> submit(Runnable task, T result) {
Future<T> future = realService.submit(task, result);
synchronized (this) {
futures.add(future);
}
return future;
}
#Override
public Future<?> submit(Runnable task) {
Future<?> future = realService.submit(task);
synchronized (this) {
futures.add(future);
}
return future;
}
#Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
List<Future<T>> future = realService.invokeAll(tasks);
synchronized (this) {
futures.addAll(future);
}
return future;
}
#Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException {
List<Future<T>> future = realService.invokeAll(tasks, timeout, unit);
synchronized (this) {
futures.addAll(future);
}
return future;
}
#Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
//don't know what to do here. Maybe this method is not needed by the framework
//than just throw new NotImplementedException();
return realService.invokeAny(tasks);
}
#Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
//don't know what to do here. Maybe this method is not needed by the framework
//than just throw new NotImplementedException();
return realService.invokeAny(tasks, timeout, unit);
}
}