|
|
俊秀的灌汤包 · 國立中央大學- 教師履歷平台· 3 月前 · |
|
|
深沉的野马 · 拿不走的记忆_百度百科· 10 月前 · |
|
|
私奔的山楂 · 宁夏医科大学2024年公开招聘高层次人才公告 ...· 10 月前 · |
|
|
爱热闹的泡面 · 好声音李琦:长得丑很自卑未来想演戏_手机新浪网· 2 年前 · |
|
|
俊秀的毛衣 · 谷歌浏览器单文件版32位/64位绿色版· 2 年前 · |
|
|
重感情的煎鸡蛋 · 探访元上都遗址-新华网· 2 年前 · |
FutureTask
. Tasks exposes
additional state and observable properties useful for programming asynchronous
tasks in JavaFX, as defined in the
Worker
interface. An implementation
of Task must override the
call()
method. This method
is invoked on the background thread. Any state which is used in this method
must be safe to read and write from a background thread. For example, manipulating
a live scene graph from this method is unsafe and will result in runtime
exceptions.
Tasks are flexible and extremely useful for the encapsulation of "work". Because
Service
is designed to execute a Task, any Tasks defined by the application
or library code can easily be used with a Service. Likewise, since Task extends
from FutureTask, it is very easy and natural to use a Task with the java concurrency
Executor
API. Since a Task is Runnable, you
can also call it directly (by invoking the
FutureTask.run()
method)
from another background thread. This allows for composition of work, or pass it to
a new Thread constructed and executed manually. Finally, since you can
manually create a new Thread, passing it a Runnable, it is possible to use
the following idiom:
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
Note that this code sets the daemon flag of the Thread to true. If you
want a background thread to prevent the VM from existing after the last
stage is closed, then you would want daemon to be false. However, if
you want the background threads to simply terminate after all the
stages are closed, then you must set daemon to true.
Although
ExecutorService
defines several methods which
take a Runnable, you should generally limit yourself to using the
execute
method inherited from
Executor
.
As with FutureTask, a Task is a one-shot class and cannot be reused. See
Service
for a reusable
Worker
.
Because the Task is designed for use with JavaFX GUI applications, it ensures
that every change to its public properties, as well as change notifications
for state, errors, and for event handlers, all occur on the main JavaFX application
thread. Accessing these properties from a background thread (including the
call()
method) will result in runtime exceptions being raised. The only exception
to this, is when initially configuring a Task, which may safely be done
from any thread. However, once the Task has been initialized and
started, it may only thereafter be used from the FX thread (except for those methods clearly
marked as being appropriate for the subclass to invoke from the background thread).
It is
strongly encouraged
that all Tasks be initialized with
immutable state upon which the Task will operate. This should be done by providing
a Task constructor which takes the parameters necessary for execution of the Task.
Immutable state makes it easy and safe to use from any thread and ensures
correctness in the presence of multiple threads.
In Java there is no reliable way to "kill" a thread in process. However,
when
cancel
is called on a Task, it is important that
the Task stop processing. A "run-away" Task might continue processing
and updating the message, text, and progress properties even after the
Task has been cancelled! In Java, cancelling a Task is a cooperative
endeavor. The user of the Task will request that it be cancelled, and
the author of the Task must check whether is has been cancelled within
the body of the
call
method. There are two ways this can
be done. First, the Task author may check the isCancelled method,
inherited from
FutureTask
, to see whether the Task has
been cancelled. Second, if the Task implementation makes use of any
blocking calls (such as NIO InterruptibleChannels or Thread.sleep) and
the task is cancelled while in such a blocking call, an
InterruptedException is thrown. Task implementations which have blocking
calls should recognize that an interrupted thread may be the signal for
a cancelled task and should double check the isCancelled method to ensure
that the InterruptedException was thrown due to the cancellation of the
Task.
call
method, we iterate from
0 to 100000. On each iteration, we check to see whether this Task has
been cancelled. If it has been, then we break out of the loop and return
the number of times we iterated. Otherwise a message is printed to
the console and the iteration count increased and we continue looping.
Checking for isCancelled() in the loop body is critical, otherwise the
developer may cancel the task, but the task will continue running
and updating both the progress and returning the incorrect result
from the end of the
call
method. A correct implementation
of a Task will always check for cancellation.
Thread.sleep
call. Since this is a blocking call, I have to handle the potential
InterruptedException. Within the catch block, I will check whether
the Task has been cancelled, and if so, update the message accordingly
and break out of the loop.
call
method does not read or
modify any shared state. There are two techniques most useful for
doing this: using final variables, and passing variables to a Task
during construction.
When using a Task as an anonymous class, the most natural way to pass
parameters to the Task is by using final variables. In this example,
we pass to the Task the total number of times the Task should iterate.
final int totalIterations = 9000000;
Task<Integer> task = new Task<Integer>() {
@Override protected Integer call() throws Exception {
int iterations;
for (iterations = 0; iterations < totalIterations; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
updateMessage("Iteration " + iterations);
updateProgress(iterations, totalIterations);
return iterations;
Since
totalIterations
is final, the
call
method can safely read it and refer to it from a background thread.
When writing Task libraries (as opposed to specific-use implementations),
we need to use a different technique. In this case, I will create an
IteratingTask which performs the same work as above. This time, since
the IteratingTask is defined in its own file, it will need to have
parameters passed to it in its constructor. These parameters are
assigned to final variables.
public class IteratingTask extends Task<Integer> {
private final int totalIterations;
public IteratingTask(int totalIterations) {
this.totalIterations = totalIterations;
@Override protected Integer call() throws Exception {
int iterations = 0;
for (iterations = 0; iterations < totalIterations; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
updateMessage("Iteration " + iterations);
updateProgress(iterations, totalIterations);
return iterations;
And then when used:
IteratingTask task = new IteratingTask(8000000);
In this way, parameters are passed to the IteratingTask in a safe
manner, and again, are final. Thus, the
call
method can
safely read this state from a background thread.
WARNING: Do not pass mutable state to a Task and then operate on it from a background thread. Doing so may introduce race conditions. In particular, suppose you had a SaveCustomerTask which took a Customer in its constructor. Although the SaveCustomerTask may have a final reference to the Customer, if the Customer object is mutable, then it is possible that both the SaveCustomerTask and some other application code will be reading or modifying the state of the Customer from different threads. Be very careful in such cases, that while a mutable object such as this Customer is being used from a background thread, that it is not being used also from another thread. In particular, if the background thread is reading data from the database and updating the Customer object, and the Customer object is bound to scene graph nodes (such as UI controls), then there could be a violation of threading rules! For such cases, modify the Customer object from the FX Application Thread rather than from the background thread.
public class UpdateCustomerTask extends Task<Customer> { private final Customer customer; public UpdateCustomerTask(Customer customer) { this.customer = customer; @Override protected Customer call() throws Exception { // pseudo-code: // query the database // read the values // Now update the customer Platform.runLater(new Runnable() { @Override public void run() { customer.setF setFirstName(rs.getString("FirstName")); // etc return customer;
null
. You would use it as follows:
final String filePath = "/foo.txt";
final String contents = "Some contents";
Task<Void> task = new Task<Void>() {
@Override protected Void call() throws Exception {
File file = new File(filePath);
FileOutputStream out = new FileOutputStream(file);
// ... and other code to write the contents ...
// Return null at the end of a Task of type Void
return null;
Because the ListView, TableView, and other UI controls and scene graph
nodes make use of ObservableList, it is common to want to create and return
an ObservableList from a Task. When you do not care to display intermediate
values, the easiest way to correctly write such a Task is simply to
construct an ObservableList within the
call
method, and then
return it at the conclusion of the Task.
In the above example, we are going to create 100 rectangles and return
them from this task. An ObservableList is created within the
call
method, populated, and then returned.
Sometimes you want to create a Task which will return partial results. Perhaps you are building a complex scene graph and want to show the scene graph as it is being constructed. Or perhaps you are reading a large amount of data over the network and want to display the entries in a TableView as the data is arriving. In such cases, there is some shared state available both to the FX Application Thread and the background thread. Great care must be taken to never update shared state from any thread other than the FX Application Thread .
The easiest way to do this is to take advantage of the
updateValue(Object)
method.
This method may be called repeatedly from the background thread. Updates are coalesced to
prevent saturation of the FX event queue. This means you can call it as frequently as
you like from the background thread but only the most recent set is ultimately set.
Another way to do this is to expose a new property on the Task
which will represent the partial result. Then make sure to use
Platform.runLater
when updating the partial result.
Suppose instead of updating a single value, you want to populate an ObservableList
with results as they are obtained. One approach is to expose a new property on the Task
which will represent the partial result. Then make sure to use
Platform.runLater
when adding new items to the partial
result.
Generally, Tasks should not interact directly with the UI. Doing so
creates a tight coupling between a specific Task implementation and a
specific part of your UI. However, when you do want to create such a
coupling, you must ensure that you use
Platform.runLater
so that any modifications of the scene graph occur on the
FX Application Thread.
Sometimes you may want to write a Task which updates its progress, message, text, or in some other way reacts whenever a state change happens on the Task. For example, you may want to change the status message on the Task on Failure, Success, Running, or Cancelled state changes. Task<Integer> task = new Task<Integer>() { @Override protected Integer call() throws Exception { int iterations = 0; for (iterations = 0; iterations < 100000; iterations++) { if (isCancelled()) { break; System.out.println("Iteration " + iterations); return iterations; @Override protected void succeeded() { super.succeeded(); updateMessage("Done!"); @Override protected void cancelled() { super.cancelled(); updateMessage("Cancelled!"); @Override protected void failed() { super.failed(); updateMessage("Failed!");
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onCancelled
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onFailed
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onRunning
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onScheduled
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onSucceeded
ReadOnlyDoubleProperty
progress
ReadOnlyBooleanProperty
running
ReadOnlyObjectProperty
<
Worker.State
>
state
ReadOnlyStringProperty
title
ReadOnlyDoubleProperty
totalWork
ReadOnlyObjectProperty
<
V
>
value
ReadOnlyDoubleProperty
workDone
<T extends
Event
>
void
addEventFilter
(
EventType
<T> eventType,
EventHandler
<? super T> eventFilter)
<T extends
Event
>
void
addEventHandler
(
EventType
<T> eventType,
EventHandler
<? super T> eventHandler)
EventDispatchChain
buildEventDispatchChain
(
EventDispatchChain
tail)
protected abstract
V
call
()
boolean
cancel
()
boolean
cancel
(boolean mayInterruptIfRunning)
protected void
cancelled
()
ReadOnlyObjectProperty
<
Throwable
>
exceptionProperty
()
protected void
failed
()
fireEvent
(
Event
event)
Throwable
getException
()
String
getMessage
()
EventHandler
<
WorkerStateEvent
>
getOnCancelled
()
EventHandler
<
WorkerStateEvent
>
getOnFailed
()
EventHandler
<
WorkerStateEvent
>
getOnRunning
()
EventHandler
<
WorkerStateEvent
>
getOnScheduled
()
EventHandler
<
WorkerStateEvent
>
getOnSucceeded
()
double
getProgress
()
Worker.State
getState
()
String
getTitle
()
double
getTotalWork
()
getValue
()
double
getWorkDone
()
boolean
isRunning
()
ReadOnlyStringProperty
messageProperty
()
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onCancelledProperty
()
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onFailedProperty
()
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onRunningProperty
()
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onScheduledProperty
()
ObjectProperty
<
EventHandler
<
WorkerStateEvent
>>
onSucceededProperty
()
ReadOnlyDoubleProperty
progressProperty
()
<T extends
Event
>
void
removeEventFilter
(
EventType
<T> eventType,
EventHandler
<? super T> eventFilter)
<T extends
Event
>
void
removeEventHandler
(
EventType
<T> eventType,
EventHandler
<? super T> eventHandler)
protected void
running
()
ReadOnlyBooleanProperty
runningProperty
()
protected void
scheduled
()
protected <T extends
Event
>
void
setEventHandler
(
EventType
<T> eventType,
EventHandler
<? super T> eventHandler)
setOnCancelled
(
EventHandler
<
WorkerStateEvent
> value)
setOnFailed
(
EventHandler
<
WorkerStateEvent
> value)
setOnRunning
(
EventHandler
<
WorkerStateEvent
> value)
setOnScheduled
(
EventHandler
<
WorkerStateEvent
> value)
setOnSucceeded
(
EventHandler
<
WorkerStateEvent
> value)
ReadOnlyObjectProperty
<
Worker.State
>
stateProperty
()
protected void
succeeded
()
ReadOnlyStringProperty
titleProperty
()
ReadOnlyDoubleProperty
totalWorkProperty
()
protected void
updateMessage
(
String
message)
message
property.
protected void
updateProgress
(double workDone,
double max)
workDone
,
totalWork
,
and
progress
properties.
protected void
updateProgress
(long workDone,
long max)
workDone
,
totalWork
,
and
progress
properties.
protected void
updateTitle
(
String
title)
title
property.
protected void
updateValue
(
V
value)
value
property.
ReadOnlyObjectProperty
<
V
>
valueProperty
()
ReadOnlyDoubleProperty
workDoneProperty
()
public final ObjectProperty<EventHandler<WorkerStateEvent>> onScheduledProperty
getOnScheduled()
,
setOnScheduled(EventHandler)
public final ObjectProperty<EventHandler<WorkerStateEvent>> onRunningProperty
getOnRunning()
,
setOnRunning(EventHandler)
public final ObjectProperty<EventHandler<WorkerStateEvent>> onSucceededProperty
getOnSucceeded()
,
setOnSucceeded(EventHandler)
public final ObjectProperty<EventHandler<WorkerStateEvent>> onCancelledProperty
getOnCancelled()
,
setOnCancelled(EventHandler)
public final ObjectProperty<EventHandler<WorkerStateEvent>> onFailedProperty
getOnFailed()
,
setOnFailed(EventHandler)
workDoneProperty
in interface
Worker
<
V
>
getWorkDone()
totalWorkProperty
in interface
Worker
<
V
>
getTotalWork()
runningProperty
in interface
Worker
<
V
>
isRunning()
messageProperty
in interface
Worker
<
V
>
getMessage()
protected abstract V call() throws Exception
Exception
- an unhandled exception which occurred during the
background operation
public final ReadOnlyObjectProperty<Worker.State> stateProperty()
Worker
stateProperty
in interface
Worker
<
V
>
getState()
public final ObjectProperty<EventHandler<WorkerStateEvent>> onScheduledProperty()
getOnScheduled()
,
setOnScheduled(EventHandler)
public final EventHandler<WorkerStateEvent> getOnScheduled()
public final void setOnScheduled(EventHandler<WorkerStateEvent> value)
value
- the event handler, can be null to clear it
protected void scheduled()
public final ObjectProperty<EventHandler<WorkerStateEvent>> onRunningProperty()
getOnRunning()
,
setOnRunning(EventHandler)
public final EventHandler<WorkerStateEvent> getOnRunning()
public final void setOnRunning(EventHandler<WorkerStateEvent> value)
value
- the event handler, can be null to clear it
protected void running()
public final ObjectProperty<EventHandler<WorkerStateEvent>> onSucceededProperty()
getOnSucceeded()
,
setOnSucceeded(EventHandler)
public final EventHandler<WorkerStateEvent> getOnSucceeded()
public final void setOnSucceeded(EventHandler<WorkerStateEvent> value)
value
- the event handler, can be null to clear it
protected void succeeded()
public final ObjectProperty<EventHandler<WorkerStateEvent>> onCancelledProperty()
getOnCancelled()
,
setOnCancelled(EventHandler)
public final EventHandler<WorkerStateEvent> getOnCancelled()
public final void setOnCancelled(EventHandler<WorkerStateEvent> value)
value
- the event handler, can be null to clear it
protected void cancelled()
public final ObjectProperty<EventHandler<WorkerStateEvent>> onFailedProperty()
getOnFailed()
,
setOnFailed(EventHandler)
public final EventHandler<WorkerStateEvent> getOnFailed()
public final void setOnFailed(EventHandler<WorkerStateEvent> value)
value
- the event handler, can be null to clear it
protected void failed()
public final ReadOnlyObjectProperty<V> valueProperty()
Worker
valueProperty
in interface
Worker
<
V
>
getValue()
public final Throwable getException()
getException
in interface
Worker
<
V
>
public final ReadOnlyObjectProperty<Throwable> exceptionProperty()
Worker
exceptionProperty
in interface
Worker
<
V
>
getException()
public final ReadOnlyDoubleProperty workDoneProperty()
Worker
workDoneProperty
in interface
Worker
<
V
>
getWorkDone()
public final ReadOnlyDoubleProperty totalWorkProperty()
Worker
totalWorkProperty
in interface
Worker
<
V
>
getTotalWork()
public final ReadOnlyDoubleProperty progressProperty()
Worker
progressProperty
in interface
Worker
<
V
>
getProgress()
public final ReadOnlyBooleanProperty runningProperty()
Worker
runningProperty
in interface
Worker
<
V
>
isRunning()
public final ReadOnlyStringProperty messageProperty()
Worker
messageProperty
in interface
Worker
<
V
>
getMessage()
public final ReadOnlyStringProperty titleProperty()
Worker
titleProperty
in interface
Worker
<
V
>
getTitle()
public final boolean cancel()
Worker
cancel
in interface
Worker
<
V
>
workDone
,
totalWork
,
and
progress
properties. Calls to updateProgress
are coalesced and run later on the FX application thread, and calls
to updateProgress, even from the FX Application thread, may not
necessarily result in immediate updates to these properties, and
intermediate workDone values may be coalesced to save on event
notifications.
max
becomes the new value for
totalWork
.
This method is safe to be called from any thread.
workDone
- A value from Long.MIN_VALUE up to max. If the value is greater
than max, then it will be clamped at max.
If the value passed is negative then the resulting percent
done will be -1 (thus, indeterminate).
max
- A value from Long.MIN_VALUE to Long.MAX_VALUE.
updateProgress(double, double)
protected void updateProgress(double workDone,
double max)
workDone
,
totalWork
,
and
progress
properties. Calls to updateProgress
are coalesced and run later on the FX application thread, and calls
to updateProgress, even from the FX Application thread, may not
necessarily result in immediate updates to these properties, and
intermediate workDone values may be coalesced to save on event
notifications.
max
becomes the new value for
totalWork
.
This method is safe to be called from any thread.
workDone
- A value from Double.MIN_VALUE up to max. If the value is greater
than max, then it will be clamped at max.
If the value passed is negative, or Infinity, or NaN,
then the resulting percentDone will be -1 (thus, indeterminate).
max
- A value from Double.MIN_VALUE to Double.MAX_VALUE. Infinity and NaN are treated as -1.
protected void updateMessage(String message)
message
property. Calls to updateMessage
are coalesced and run later on the FX application thread, so calls
to updateMessage, even from the FX Application thread, may not
necessarily result in immediate updates to this property, and
intermediate message values may be coalesced to save on event
notifications.
This method is safe to be called from any thread.
message
- the new message
protected void updateTitle(String title)
title
property. Calls to updateTitle
are coalesced and run later on the FX application thread, so calls
to updateTitle, even from the FX Application thread, may not
necessarily result in immediate updates to this property, and
intermediate title values may be coalesced to save on event
notifications.
This method is safe to be called from any thread.
title
- the new title
protected void updateValue(V value)
value
property. Calls to updateValue
are coalesced and run later on the FX application thread, so calls
to updateValue, even from the FX Application thread, may not
necessarily result in immediate updates to this property, and
intermediate values may be coalesced to save on event
notifications.
This method is safe to be called from any thread.
value
- the new value
public final <T extends Event> void addEventHandler(EventType<T> eventType, EventHandler<? super T> eventHandler)
T
- the specific event class of the handler
eventType
- the type of the events to receive by the handler
eventHandler
- the handler to register
NullPointerException
- if the event type or handler is null
public final <T extends Event> void removeEventHandler(EventType<T> eventType, EventHandler<? super T> eventHandler)
T
- the specific event class of the handler
eventType
- the event type from which to unregister
eventHandler
- the handler to unregister
NullPointerException
- if the event type or handler is null
public final <T extends Event> void addEventFilter(EventType<T> eventType, EventHandler<? super T> eventFilter)
T
- the specific event class of the filter
eventType
- the type of the events to receive by the filter
eventFilter
- the filter to register
NullPointerException
- if the event type or filter is null
public final <T extends Event> void removeEventFilter(EventType<T> eventType, EventHandler<? super T> eventFilter)
T
- the specific event class of the filter
eventType
- the event type from which to unregister
eventFilter
- the filter to unregister
NullPointerException
- if the event type or filter is null
protected final <T extends Event> void setEventHandler(EventType<T> eventType, EventHandler<? super T> eventHandler)
T
- the specific event class of the handler
eventType
- the event type to associate with the given eventHandler
eventHandler
- the handler to register, or null to unregister
NullPointerException
- if the event type is null
public final void fireEvent(Event event)
event
- the event to fire
public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail)
EventTarget
EventTarget
. This event target is
not automatically added to the chain, so if it wants to process events,
it needs to add an
EventDispatcher
for itself to the chain.
In the case the event target is part of some hierarchy, the chain for it
is usually built from event dispatchers collected from the root of the
hierarchy to the event target.
The event dispatch chain is constructed by modifications to the provided
initial event dispatch chain. The returned chain should have the initial
chain at its end so the dispatchers should be prepended to the initial
chain.
The caller shouldn't assume that the initial chain remains unchanged nor
that the returned value will reference a different chain.
buildEventDispatchChain
in interface
EventTarget
tail
- the initial chain to build from
|
|
俊秀的灌汤包 · 國立中央大學- 教師履歷平台 3 月前 |
|
|
深沉的野马 · 拿不走的记忆_百度百科 10 月前 |
|
|
爱热闹的泡面 · 好声音李琦:长得丑很自卑未来想演戏_手机新浪网 2 年前 |
|
|
俊秀的毛衣 · 谷歌浏览器单文件版32位/64位绿色版 2 年前 |
|
|
重感情的煎鸡蛋 · 探访元上都遗址-新华网 2 年前 |