I've written a class, a series of instances of which are intended to be called from an AsyncTask, which will return a result from the method runReport(). It creates a worker thread just fine, but for some reason it then doesn't execute the Callable's call() method. What am I doing wrong?
//Problem: doStuff() never gets called, even though the worker thread gets created.
#Override
public ReportResult runReport() throws InterruptedException, ExecutionException {
Callable<ReportResult> report = new Callable<ReportResult>() {
#Override
public ReportResult call() throws Exception {
doStuff();
...
return new ReportResult(varWrittenByMethod);
}
};
FutureTask<ReportResult> result = new FutureTask<ReportResult>(report);
//I tried a few of these ExecutorService factory methods, with the same result.
//I only made my own ThreadFactory to verify the worker was created
ExecutorService es = Executors.newSingleThreadExecutor(new ThreadFact());
es.submit(report);
ReportResult finalResult = result.get();
es.shutdownNow();
return finalResult;
}
private class ThreadFact implements ThreadFactory{
#Override
public Thread newThread(Runnable r) {
Log.d(TAG, "Created worker Thread");
return new Thread(r);
}
}
As far as I can tell, I have to do this as a FutureTask in its own Thread, because it needs to do the following (all of which apart from the return is inside doStuff() ):
Do heavy some synchronous setup (The AsyncTask keeps that off the UI thread)
Call Looper.prepare()
Register a listener
Call Looper.loop(), catch a few callbacks from the listener over a period of time.
Call Looper.myLooper().quit() inside the listener callback when I have enough datapoints
Return the result
I'm open to better ways to do this. I originally let the AsyncTask make this call, then ran Looper.loop() on its thread, but I couldn't process a queue of these objects since I needed to call Looper.myLooper.quit() from the listener before returning a result, which poisoned the thread's message queue irreversibly.
Your thread factory doesn't propagate the passed Runnable to the created thread. In your ThreadFactory, try:
return new Thread(r);
Also, you should be using the FutureTask returned by the submit method, not the one you created explicitly. E.g.
FutureTask<ReportResult> result = es.submit(report);
ReportResult finalResult = result.get();
As a note, you probably will regret doing this level of work from an AsyncTask, because the threads in an AsyncTask will get killed during an Activity lifecycle change. Better to do the asynchronous setup in an IntentService. If you don't need Looper(), you can use plain threads rather than HandlerThreads.
Related
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
when going through the ListenableFutre interface, it notes in the doc that
addListener()
Registers a listener to be run on the given executor. The listener
will run when the Future's computation is complete or, if the
computation is already complete, immediately.`
Since Future.get() is a blocking call, how does Java guarantee certain future is Done? are they spinning on this? I understand that with Framework like dagger producers, it is kinda easy to understand (once task is done, write to something, the monitoring thread will be notified). in ListenableFuture case, does jvm support something like this out of box?
using wait()/notify() like mechanism ?
FollowUp Question: as all of you put, it is the caller actually guarantee the listener to be run, normal case to use a ListenableFuture
would be ListenableFuture future = Caller.call(), with caller and callee in different threads or even in different JVMs, how is this done in java? the listener in stored in both the caller thread and callee thread ? or using remote reigstery when in differnt JVMs?
There's nothing magic going on with ListenableFuture - the contract of the interface simply requires that any implementations invoke any registered listeners upon completion (or immediately, if already done).
It may help to look at one such implementation, AbstractFuture - specifically look at the .complete() method, which is invoked immediately after the future becomes "done" (by finishing, failing, or being cancelled). In order to be both fast and thread-safe the details are somewhat complex, but essentially that's all it does.
As already mentioned, the best way to understand the ListenableFuture is to look how it is implemented. When you call addListener(Runnable listener, Executor exec), you provide a Runnable listener and an Executor to run this listener, so it is you who decides how your listener is executed.
the listener is stored in both the caller thread and callee thread ?
The listener is stored inside the future, in the ExecutionList:
// The execution list to hold our executors.
private final ExecutionList executionList = new ExecutionList();
And addListener(Runnable listener, Executor exec) does just following:
public void addListener(Runnable listener, Executor exec) {
executionList.add(listener, exec);
}
So when the future completes, it calls the set(V value) method:
protected boolean set(#Nullable V value) {
boolean result = sync.set(value);
if (result) {
executionList.execute();
}
return result;
}
and all listeners are executed like this: executor.execute(runnable);
I'd like to add answers.
Guava does not garantee it.
If you down JVM or JVM is crashed no listeners would be invoked.
If you shutdown executor without cancelling futures, no listeners would be invoked too. I mean this case:
ExecutorService executorService = Executors.newSingleThreadExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(false);
return t;
}
});
ListenableFuture<?> listenableFuture = JdkFutureAdapters.listenInPoolThread(
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run!!!");
}
}),
executorService
);
Futures.addCallback(listenableFuture, new FutureCallback<Object>() {
#Override
public void onSuccess(#Nullable Object result) {
System.out.println("onSuccess");
}
#Override
public void onFailure(Throwable t) {
System.out.println("onFailure");
}
});
MoreExecutors.shutdownAndAwaitTermination(executorService, 3, TimeUnit.SECONDS);
I didn't see "onSuccess" or "onFailure", did you?
In usual workflow when JVM is running, Guava uses CAS to invoke listeners exactly once, you can see it in source code too.
I want to execute a specific method which contains a service call. As it includes a service call , it will take some time for execution. I want to add a timer which will keep program in wait till that method completes its executiuon. Any work around for this?
You can organize an asynchroneous method execution with a timeout with java.util.concurrent package
ExecutorService executorService = ...
Object res = executorService.submit(new Callable<Object>() {
public Object call() throws Exception {
... your logic
}
}).get(timeout, TimeUnit.MILLISECONDS);
You can use a separate thread to call that service and using join() method of Thread class, you can force main program to wait until that thread finishes the execution.
Sheduler
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand(){
#Override
public void execute() {
// code here
}
I am confused on the following:
To use threads in a Java program, the simplest way is to extend Thread class and implement the runnable interface (or simply implement runnable).
To start the thread's execution. we must call the Thread's method start(), which in turn calls method run() of the thread. And so the thread starts.
The method start() (unless I am wrong) must be called exactly and only once for each thread. As a result, thread instances can not be reused unless somehow the run method itself runs in some-short of infinite loop that facilitates a custom implementation of the thread's reusage.
Now the javadoc
link text
says
Calls to execute will reuse previously constructed threads if available
I do not understand how this is implemented.
I provide in the execute method of the executor method my custom thread e.g.
ExecutorService myCachedPool = Executors.newCachedThreadPool();
myCachedPool.execute(new Runnable(){public void run(){
//do something time consuming
}});
How can this custom thread I delegeate to the executor framework be reused?
Is Executor is allowed to call method start() more than 1 time, while we can not in our programs?
Am I misunderstanding something?
Thank you.
Note that it's not Executor that calls start() - it's ExecutorService. And no, it's not calling start() twice. It doesn't start the task that you give it directly using Thread.start()... instead, it starts a thread which knows about that thread pool's queue of work. The thread will basically wait until there's some work to do, then pick it up and execute it, before going back to waiting. So although the thread performs several tasks, Thread.start() is only called once.
EDIT: Judging by the comments, you're a bit confused about the difference between a Runnable (which is a task to be executed) and a Thread (which is what executes tasks).
The same thread can execute multiple tasks. For a very simple example not using a thread pool, consider this:
public class MultiRunnable implements Runnable
{
private final List<Runnable> runnables;
public MultiRunnable(List<Runnable> runnables)
{
this.runnables = runnables;
}
public void run()
{
for (Runnable runnable : runnables)
{
runnable.run();
}
}
}
(Ignore the potential thread safety issues of using a List<T> from multiple threads.)
You could create a whole bunch of Runnable tasks capable of doing different things, then create a single MultiRunnable to run them in turn. Pass that instance of MultiRunnable into the Thread constructor, and then when you start the thread, it will execute each of the original runnable tasks. Does that help?
It is not calling start() more than once; instead the Thread in the pool never completes, but just stays alive---waiting. The source code is available for download if you want to look at it.
Each Thread in the thread pool can simply wait() for the Executor to hand it a new Runnable, but the Thread's own run() method has not completed. It simply waits for a new Runnable to be given to the Executor.
To "start" a thread more than once, create a runnable. For example:
//NO
private class T extends Thread { //not necessary to implement runnable
public void run(){
//...
}
}
void someMethod(){
T a = new T();
a.start();
a.start(); //NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO
}
Instead,
//Yes
private class T implements Runnable {
public void run(){
//...
}
}
void someMethod(){
T a = new T();
new Thread(a).start();
new Thread(a).start(); //YES YES YES
}
It is also possible to do this:
void someMethod(){
final Runnable r = new Runnable(){
public void run(){
//...
}
};
new Thread(r).start();
new Thread(r).start();
}
// r could also be a field of you class.
I have an object with a method named StartDownload(), that starts three threads.
How do I get a notification when each thread has finished executing?
Is there a way to know if one (or all) of the thread is finished or is still executing?
There are a number of ways you can do this:
Use Thread.join() in your main thread to wait in a blocking fashion for each Thread to complete, or
Check Thread.isAlive() in a polling fashion -- generally discouraged -- to wait until each Thread has completed, or
Unorthodox, for each Thread in question, call setUncaughtExceptionHandler to call a method in your object, and program each Thread to throw an uncaught Exception when it completes, or
Use locks or synchronizers or mechanisms from java.util.concurrent, or
More orthodox, create a listener in your main Thread, and then program each of your Threads to tell the listener that they have completed.
How to implement Idea #5? Well, one way is to first create an interface:
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
then create the following class:
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners
= new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
#Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}
public abstract void doRun();
}
and then each of your Threads will extend NotifyingThread and instead of implementing run() it will implement doRun(). Thus when they complete, they will automatically notify anyone waiting for notification.
Finally, in your main class -- the one that starts all the Threads (or at least the object waiting for notification) -- modify that class to implement ThreadCompleteListener and immediately after creating each Thread add itself to the list of listeners:
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
then, as each Thread exits, your notifyOfThreadComplete method will be invoked with the Thread instance that just completed (or crashed).
Note that better would be to implements Runnable rather than extends Thread for NotifyingThread as extending Thread is usually discouraged in new code. But I'm coding to your question. If you change the NotifyingThread class to implement Runnable then you have to change some of your code that manages Threads, which is pretty straightforward to do.
Solution using CyclicBarrier
public class Downloader {
private CyclicBarrier barrier;
private final static int NUMBER_OF_DOWNLOADING_THREADS;
private DownloadingThread extends Thread {
private final String url;
public DownloadingThread(String url) {
super();
this.url = url;
}
#Override
public void run() {
barrier.await(); // label1
download(url);
barrier.await(); // label2
}
}
public void startDownload() {
// plus one for the main thread of execution
barrier = new CyclicBarrier(NUMBER_OF_DOWNLOADING_THREADS + 1); // label0
for (int i = 0; i < NUMBER_OF_DOWNLOADING_THREADS; i++) {
new DownloadingThread("http://www.flickr.com/someUser/pic" + i + ".jpg").start();
}
barrier.await(); // label3
displayMessage("Please wait...");
barrier.await(); // label4
displayMessage("Finished");
}
}
label0 - cyclic barrier is created with number of parties equal to the number of executing threads plus one for the main thread of execution (in which startDownload() is being executed)
label 1 - n-th DownloadingThread enters the waiting room
label 3 - NUMBER_OF_DOWNLOADING_THREADS have entered the waiting room. Main thread of execution releases them to start doing their downloading jobs in more or less the same time
label 4 - main thread of execution enters the waiting room. This is the 'trickiest' part of the code to understand. It doesn't matter which thread will enter the waiting room for the second time. It is important that whatever thread enters the room last ensures that all the other downloading threads have finished their downloading jobs.
label 2 - n-th DownloadingThread has finished its downloading job and enters the waiting room. If it is the last one i.e. already NUMBER_OF_DOWNLOADING_THREADS have entered it, including the main thread of execution, main thread will continue its execution only when all the other threads have finished downloading.
You should really prefer a solution that uses java.util.concurrent. Find and read Josh Bloch and/or Brian Goetz on the topic.
If you are not using java.util.concurrent.* and are taking responsibility for using Threads directly, then you should probably use join() to know when a thread is done. Here is a super simple Callback mechanism. First extend the Runnable interface to have a callback:
public interface CallbackRunnable extends Runnable {
public void callback();
}
Then make an Executor that will execute your runnable and call you back when it is done.
public class CallbackExecutor implements Executor {
#Override
public void execute(final Runnable r) {
final Thread runner = new Thread(r);
runner.start();
if ( r instanceof CallbackRunnable ) {
// create a thread to perform the callback
Thread callerbacker = new Thread(new Runnable() {
#Override
public void run() {
try {
// block until the running thread is done
runner.join();
((CallbackRunnable)r).callback();
}
catch ( InterruptedException e ) {
// someone doesn't want us running. ok, maybe we give up.
}
}
});
callerbacker.start();
}
}
}
The other sort-of obvious thing to add to your CallbackRunnable interface is a means to handle any exceptions, so maybe put a public void uncaughtException(Throwable e); line in there and in your executor, install a Thread.UncaughtExceptionHandler to send you to that interface method.
But doing all that really starts to smell like java.util.concurrent.Callable. You should really look at using java.util.concurrent if your project permits it.
Many things have been changed in last 6 years on multi-threading front.
Instead of using join() and lock API, you can use
1.ExecutorService invokeAll() API
Executes the given tasks, returning a list of Futures holding their status and results when all complete.
2.CountDownLatch
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.
3.ForkJoinPool or newWorkStealingPool() in Executors is other way
4.Iterate through all Future tasks from submit on ExecutorService and check the status with blocking call get() on Future object
Have a look at related SE questions:
How to wait for a thread that spawns it's own thread?
Executors: How to synchronously wait until all tasks have finished if tasks are created recursively?
Do you want to wait for them to finish? If so, use the Join method.
There is also the isAlive property if you just want to check it.
You can interrogate the thread instance with getState() which returns an instance of Thread.State enumeration with one of the following values:
* NEW
A thread that has not yet started is in this state.
* RUNNABLE
A thread executing in the Java virtual machine is in this state.
* BLOCKED
A thread that is blocked waiting for a monitor lock is in this state.
* WAITING
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
* TIMED_WAITING
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
* TERMINATED
A thread that has exited is in this state.
However I think it would be a better design to have a master thread which waits for the 3 children to finish, the master would then continue execution when the other 3 have finished.
You could also use the Executors object to create an ExecutorService thread pool. Then use the invokeAll method to run each of your threads and retrieve Futures. This will block until all have finished execution. Your other option would be to execute each one using the pool and then call awaitTermination to block until the pool is finished executing. Just be sure to call shutdown() when you're done adding tasks.
I would suggest looking at the javadoc for Thread class.
You have multiple mechanisms for thread manipulation.
Your main thread could join() the three threads serially, and would then not proceed until all three are done.
Poll the thread state of the spawned threads at intervals.
Put all of the spawned threads into a separate ThreadGroup and poll the activeCount() on the ThreadGroup and wait for it to get to 0.
Setup a custom callback or listener type of interface for inter-thread communication.
I'm sure there are plenty of other ways I'm still missing.
I guess the easiest way is to use ThreadPoolExecutor class.
It has a queue and you can set how many threads should be working in parallel.
It has nice callback methods:
Hook methods
This class provides protected overridable beforeExecute(java.lang.Thread, java.lang.Runnable) and afterExecute(java.lang.Runnable, java.lang.Throwable) methods that are called before and after execution of each task. These can be used to manipulate the execution environment; for example, reinitializing ThreadLocals, gathering statistics, or adding log entries. Additionally, method terminated() can be overridden to perform any special processing that needs to be done once the Executor has fully terminated.
which is exactly what we need. We will override afterExecute() to get callbacks after each thread is done and will override terminated() to know when all threads are done.
So here is what you should do
Create an executor:
private ThreadPoolExecutor executor;
private int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
private void initExecutor() {
executor = new ThreadPoolExecutor(
NUMBER_OF_CORES * 2, //core pool size
NUMBER_OF_CORES * 2, //max pool size
60L, //keep aive time
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>()
) {
#Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
//Yet another thread is finished:
informUiAboutProgress(executor.getCompletedTaskCount(), listOfUrisToProcess.size());
}
}
};
#Override
protected void terminated() {
super.terminated();
informUiThatWeAreDone();
}
}
And start your threads:
private void startTheWork(){
for (Uri uri : listOfUrisToProcess) {
executor.execute(new Runnable() {
#Override
public void run() {
doSomeHeavyWork(uri);
}
});
}
executor.shutdown(); //call it when you won't add jobs anymore
}
Inside method informUiThatWeAreDone(); do whatever you need to do when all threads are done, for example, update UI.
NOTE: Don't forget about using synchronized methods since you do your work in parallel and BE VERY CAUTIOUS if you decide to call synchronized method from another synchronized method! This often leads to deadlocks
Hope this helps!
Here's a solution that is simple, short, easy to understand, and works perfectly for me. I needed to draw to the screen when another thread ends; but couldn't because the main thread has control of the screen. So:
(1) I created the global variable: boolean end1 = false; The thread sets it to true when ending. That is picked up in the mainthread by "postDelayed" loop, where it is responded to.
(2) My thread contains:
void myThread() {
end1 = false;
new CountDownTimer(((60000, 1000) { // milliseconds for onFinish, onTick
public void onFinish()
{
// do stuff here once at end of time.
end1 = true; // signal that the thread has ended.
}
public void onTick(long millisUntilFinished)
{
// do stuff here repeatedly.
}
}.start();
}
(3) Fortunately, "postDelayed" runs in the main thread, so that's where in check the other thread once each second. When the other thread ends, this can begin whatever we want to do next.
Handler h1 = new Handler();
private void checkThread() {
h1.postDelayed(new Runnable() {
public void run() {
if (end1)
// resond to the second thread ending here.
else
h1.postDelayed(this, 1000);
}
}, 1000);
}
(4) Finally, start the whole thing running somewhere in your code by calling:
void startThread()
{
myThread();
checkThread();
}
You could also use SwingWorker, which has built-in property change support. See addPropertyChangeListener() or the get() method for a state change listener example.
Look at the Java documentation for the Thread class. You can check the thread's state. If you put the three threads in member variables, then all three threads can read each other's states.
You have to be a bit careful, though, because you can cause race conditions between the threads. Just try to avoid complicated logic based on the state of the other threads. Definitely avoid multiple threads writing to the same variables.