This question already has an answer here:
JavaFX2: Can I pause a background Task / Service?
(1 answer)
Closed 8 years ago.
A worker thread is used to process a very long-running task. At the middle of task execution, a user interaction is needed to acquire inputs. As the inputs are supplied, the worker thread will resume execution. My problem is, the worker thread needs to be suspended, get inputs (shall we say through a dialog box - I am using the Dialogs API of JDK8u40 which must be facilitated by the JavaFX App Thread), and resume thereafter. The inputs are not supplied at the start due to dependency of certain situations, and inputs might be needed many times.
A typical example is, files are being copied from one directory to another. As the files are copied, a file with the same file name exists in the destination directory, thus a user interaction is needed to rename the file or skip file copying to avoid file name conflict. In this scenario, the worker thread is supposed to execute file copying, and is needed to be suspended to acquire inputs from user (must be facilitated by the JavaFX App Thread) before proceeding. Platform.runlater(() -> {}); can't do this kind of situation, for it would just queued the Runnable object to be ran at some time in the future.
How to facilitate this scenario? I am new to JavaFX concurrency.
You can use the wait notify mechanism as described here: http://www.avajava.com/tutorials/lessons/how-do-i-use-the-wait-and-notify-methods.html.
When an interaction is needed a runnable is launched through ui thread to prompt the user. The worker thread calls wait. The ui thread eventually gets the user input and notifies the working thread which continues his job according to the message it receives. The difference here is that you do not need to create two threads as the ui thread already exists.
Related
This question already has answers here:
To multi-thread or not to multi-thread!
(5 answers)
Closed 8 years ago.
I have a general question.
I have been reading a Java book and I came across a program that uses Threads. Book stated that Threads are used for multiprocessing. I want to know that if I write :
Thread t=new Thread(new classname);
t.start;
//after it some GUI code to display the input received from user in run method
and I override run method to get input from user,then, will it wait for input and then perform GUI tasks like opening frame or it will perform both tasks simultaneously.
They'll happen simultaneously. (Unless you block one of the threads using locks or a semaphore.)
If the gui thread relies on the input processing of the other thread, you'll have a race condition. So you'll definitely want to block the gui thread until the other thread is done producing whatever the gui thread needs.
As for why threads are needed, well, it's so tasks can be done simultaneously so programs can do their jobs faster.
Is there some way to verify that code is executing on the user’s user interface thread (event loop thread)?
This question is the Vaadin equivalent of this question, Swing verify code on Event Dispatch Thread at runtime.
I know how to call UI::access from a background thread to schedule a Runnable to be run on the user-interface thread. My question is how to double-check that some executing code is indeed running on the user-interface thread.
I filed a feature request for this.
UI.getCurrent()
If UI.getCurrent() returns an instance you are (most probably) either:
On a thread started by UI interaction
On a thread that is already initiated with UI::access
To quote the Vaadin 7.3.9 doc:
… In other cases, (e.g. from background threads), the current UI is not automatically defined.
Example Code
boolean uiOrUiAccessManagedThread = UI.getCurrent() != null;
The framework is already full of asserts in various code paths that should only be run on the thread that has locked the UI state. The most important being whenever shared state is accessed.
To benefit from this checking, just make sure your server is run with assertion checking enabled, i.e. by starting it with the -ea JVM parameter.
In java fx controller i have two version of the code that simply sets a text on a label when a button is pressed (this is just a sample, but any other ui modification can be considered)...
first version uses Platform.runLater :
Platform.runLater(() -> {
status.setText("");
statusIndicator.setVisible(false);
});
the other one simply modifies it in ordinary thread :
status.setText("");
statusIndicator.setVisible(false);
Both are working perfectly fine, only difference i know so far is that passing some runnable to Platform.runLater will keep the order of execution.
is there any other significat difference or motive to use Platform.runLater?
JavaFX has just a single UI thread
From Docs
The JavaFX scene graph, which represents the graphical user interface
of a JavaFX application, is not thread-safe and can only be accessed
and modified from the UI thread also known as the JavaFX Application
thread
In case you have long-running tasks, you will want to run them on background threads and after completion of such threads, you would want to update the result back to the UI. Under such scenario's, you use the updation surrounded with Platform.runlater(). Surrounding your code with Platform.runLater enables your code to communicate with the JavaFX Application thread.
Coming to your question :
is there any other significat difference or motive to use Platform.runLater?
I hope most of it is already answered, just to add
1 . You don't have to use Platform.runlater(), if you are already on the JavaFX Application thread
2 . As the Platform.runLater() doc says
Run the specified Runnable on the JavaFX Application Thread at some unspecified time in the future
We are not sure when the update will take place, it depends on the number of updates waiting to be processed. If a number of updates are waiting to be processed on the UI thread, it can take some time (such scenario normally doesn't happen)
I think title itself says what the my question is...
AFAIK, in Java, when work of a Thread is completed i.e. run() method has completed executing, Thread itself will finish and dies.
So, When my Activity(I mean UI) is idle for a long time, what the UI thread will do? does it sleeps? or does it do any other work?
Thanks to all...
I believe the question is not really about Java threads in general, but about the Android "main thread" (also called the "UI thread").
To quote from the JavaDoc for the Android Handler:
When a process is created for your application, its main thread is
dedicated to running a message queue that takes care of managing the
top-level application objects (activities, broadcast receivers, etc)
and any windows they create. You can create your own threads, and
communicate back with the main application thread through a Handler.
This is done by calling the same post or sendMessage methods as
before, but from your new thread. The given Runnable or Message will
then be scheduled in the Handler's message queue and processed when
appropriate.
In other words: The main thread is responsible for dequeuing messages/runnables from a queue and processing them. That main thread is blocked while the queue is empty (since there is nothing for it to do). If you use a Handler that was created in the main thread, that Handler's messages and runnables will actually be added to the same queue used by the main thread. Normally, the main thread will run as long as the process does.
Note: An Android app can actually have multiple processes, and each one will have its own main thread. However, most Android apps will only have one process (and therefore one main thread).
I am currently developing Android app, it needs download content from internet. I use thread to do that and then call runOnUiThread method to update GUI.
I placed a refresh menu on it, if user tried to refresh the content, the download thread will be created and started. The problem is that how can I control the thread order, I need to accept the latest request's response and abandon previous thread requests if there were some other requests still running because the request parameters may have been changed by user. Currently I was using a threadId to do this thing, when a thread finished, it will check its threadId, if it was the latest recored one, it then takes control and render the response. My question is that is there any other proper better solution for this?
Do I need to stop threads when user exit the app? I remember that some book said that do not try stop thread manually and wait itself finish is a good practice, is that true? Should I stop them by calling "stop" or "interrupt" method?
I read some documents around threading in Android and found the class HandlerThread, what is it? In what kind of situation I need to use it?
Rather than starting a new thread for every refresh action I would create a single thread for all the background download work that loops and downloads content as lined up in a queue. That ensures that you don't download content concurrently and also saves resources.
In the GUI you simply queue a refresh request whenever the user prompts you to and can abort a running download by calling HttpRequestBase.abort on the http method instance. The background thread should receive and catch a SocketException and move on to the next queued request.
To end the background thread you just have to end its loop. You can use the Looper and Handler classes to help you with all of the above, the HandlerThread class you mentioned is simply a handy class to create a thread that has a Looper.
The problem with interrupting a thread is that it won't break you out of a blocking I/O request and handling an InterruptException correctly can be complicated. So depending on the situation I would say yes, it is better practice to end the thread by returning from its run method.
i discover this week AsyncTask, and i replace Thread by AsyncTask in some place in my program,
You have doc & sample here, really easy to use :
http://developer.android.com/reference/android/os/AsyncTask.html
when i was using thread GUI was lock, and now it's not locked.
And it's possible to cancel a AsyncTask (but i never try)
You can use an IntentService to start your background operations, the service will operate as "work queue processor" and will execute your calls in order.