public interface TaskDispatcher
TaskDispatcher conceals details of low-level thread implementation, including creating, destroying, and
reusing.
TaskDispatcher enables execution of synchronous, asynchronous, serial, and parallel tasks in almost all
scenarios.
The following example shows how to use this interface to post tasks to the UI thread:
void postTaskToUI(Context context) {
TaskDispatcher dispatcher = context.getUITaskDispatcher();
System.out.println("1");
dispatcher.delayDispatch(new Runnable() {
System.out.println("delay dispatch");
}, 10);
System.out.println("2");
dispatcher.asyncDispatch(new Runnable() {
System.out.println("async dispatch");
});
System.out.println("3");
dispatcher.syncDispatch(new Runnable() {
System.out.println("sync dispatch");
});
System.out.println("4");
}
// possible result is:
// 1
// 2
// 3
// async dispatch
// sync dispatch
// 4
// delay dispatch
Note: TaskDispatcher has multiple implementations for different purposes.
ParallelTaskDispatcher (created by createParallelTaskDispatcher) enables abilities to execute parallel tasks. Different from
GlobalTaskDispatcher, this task dispatcher is not globally unique. You can create multiple
ParallelTaskDispatcher objects.
SerialTaskDispatcher (created by createSerialTaskDispatcher) enables abilities to execute serial tasks. The thread where a particular task is
running, however, is not fixed. If you want to execute tasks in parallel, use a ParallelTaskDispatcher
instead of creating multiple SerialTaskDispatcher instances.
SpecTaskDispatcher (returned by getUITaskDispatcher or
getMainTaskDispatcher) is a dispatcher dedicated to a specific
thread.
Note
Deadlock: If syncDispatch is incorrectly used, a deadlock occurs in the
following scenarios:
syncDispatch is called for dispatching a task to a dedicated task dispatcher on a thread that is bound to
the dispatcher.
syncDispatch is called for dispatching a task to a serial task dispatcher on a thread that is currently
being used by a task posted by the dispatcher.
syncDispatch is repeatedly called for dispatching a task to various dispatchers but the task is finally
dispatched to the first serial task dispatcher.
syncDispatch to dispatch a task to serial task dispatcher B, while
dispatcher B is using syncDispatch to dispatch a task to dispatcher A. A deadlock occurs in a particular
thread execution sequence.
Lifecycle: The lifecycle of a task dispatcher includes three parts:
| 限定符和类型 | 方法 | 说明 |
|---|---|---|
void |
applyDispatch(Consumer<Long> task,
long iterations) |
Executes a task multiple times without waiting.
|
Revocable |
asyncDispatch(Runnable task) |
Asynchronously dispatches a task.
|
void |
asyncDispatchBarrier(Runnable task) |
Sets an execution barrier for the given task to be executed only after all tasks in the task group are
finished.
|
Revocable |
asyncGroupDispatch(Group group,
Runnable task) |
Adds a task to a task group asynchronously.
|
Group |
createDispatchGroup() |
Creates a task group.
|
Revocable |
delayDispatch(Runnable task,
long delayMs) |
Dispatches a task after the given delay.
|
void |
groupDispatchNotify(Group group,
Runnable task) |
Executes a task after all tasks in the task group are finished.
|
boolean |
groupDispatchWait(Group group,
long timeout) |
Waits all tasks in a task group to finish.
|
void |
syncDispatch(Runnable task) |
Dispatches a task and waits until the task is complete in the current thread.
|
void |
syncDispatchBarrier(Runnable task) |
Sets an execution barrier in a task group for the given task and waits for the task to be executed after all
tasks in the task group are finished.
|
void syncDispatch(Runnable task)
The current thread is blocked before the given task is complete. Therefore, a deadlock occurs in the following cases:
syncDispatch is cyclically called on a serial task dispatcher or a task dispatcher that is dedicated
to a specific thread. For example, syncDispatch is called to dispatch a task from dispatcher A to
dispatcher A, or to dispatch a task from dispatcher A to dispatcher B and then back to dispatcher A.
syncDispatch. As a result, the internal thread pool is used up and
cannot process other tasks any more.
task - Indicates the task to be executed. This parameter includes all information required for the task
execution.NullPointerException - Throws this exception if the input parameter task is null.Revocable asyncDispatch(Runnable task)
This method dispatches a task and returns a value immediately without waiting for the task to execute.
task - Indicates the task to be executed. This parameter includes all information required for the task
execution.Revocable instance used for revoking the given task if
it has not been invoked.NullPointerException - Throws this exception if the input parameter task is null.Revocable delayDispatch(Runnable task, long delayMs)
This is an asynchronous execution and returns a value immediately without waiting. The task will be
dispatched to the queue after the given delay specified by delayMs, and its actual execution time
maybe later than the given time. The time when the task will be executed depends on the length of the queue
and how busy the thread pool is.
task - Indicates the task to be executed. This parameter includes all information required for the task
execution.delayMs - Indicates the time period that the given task has to wait before being dispatched.Revocable instance used for revoking the given task
if it has not been invoked.NullPointerException - Throws this exception if the input parameter task is null.void syncDispatchBarrier(Runnable task)
The current thread is blocked until the given task is complete. Incorrect use of this method may cause a deadlock. If too many threads are blocked, resources in the thread pool will be used up.
task - Indicates the task to be executed.NullPointerException - Throws this exception if the input parameter task is null.void asyncDispatchBarrier(Runnable task)
Task execution barriers are unavailable on global task dispatchers. Example code for setting a task execution barrier:
TaskDispatcher parallelTaskDispatcher = context.createParallelTaskDispatcher(null);
parallelTaskDispatcher.asyncDispatch(new Runnable() {
public void run() {
Thread.sleep(1000); // sleep enough time
System.out.println("before barrier");
}}, 0);
parallelTaskDispatcher.asyncDispatchBarrier(new Runnable() {
public void run() {
System.out.println("Barrier");
}}, 0);
parallelTaskDispatcher.asyncDispatch(() -> {
System.out.println("after barrier");
}, 0);
// Result will be:
// before barrier
// Barrier
// after barrier
task - Indicates the task to be executed. This parameter includes all information required for the task
execution.NullPointerException - Throws this exception if the input parameter task is null.Group createDispatchGroup()
The Group object returned by this method does not contain any task. If you
need to dispatch tasks asynchronously, you can use asyncGroupDispatch(ohos.app.dispatcher.Group, java.lang.Runnable) to associate this object with
multiple tasks for monitoring the execution progress of all these tasks.
Example code for waiting for the completion of all download tasks in a task group:
void groupTest(Context context) {
TaskDispatcher dispatcher = context.createParallelTaskDispatcher();
// Creates a task group.
Group group = context.createDispatchGroup();
// Adds asynchronous tasks to the task group.
dispatcher.asyncGroupDispatch(group, () -> {
// Downloads a 10 MB file.
download(url1);
System.out.println("Finished downloading URL 1");
});
System.out.println("1");
dispatcher.asyncGroupDispatch(group, () -> {
// Downloads a 1 MB file.
download(url2);
System.out.println("Finished downloading URL 2");
});
// Executes a new task until all tasks in the task group are complete.
dispatcher.groupDispatchNotify(group, () -> {
System.out.println("All tasks finished. Do shutdown.");
};
System.out.println("2");
}
//Possible results are as follows:
// 1
// 2
// Finished downloading URL 2
// Finished downloading URL 1
// All tasks finished. Do shutdown.
Group object.Revocable asyncGroupDispatch(Group group, Runnable task)
This method returns a value immediately without waiting for the task to execute.
group - Indicates the group to which the task is added.task - Indicates the task to be executed. This parameter includes all information required for the task
execution.Revocable instance used for revoking the given task
if it has not been invoked.NullPointerException - Throws this exception if the input parameter task or group is null.boolean groupDispatchWait(Group group, long timeout)
group - Indicates the task group containing the waiting tasks.timeout - Indicates the maximum waiting time for a task.true if all tasks are correctly executed; returns false if any task times out.NullPointerException - Throws this exception if the input parameter group is null.void groupDispatchNotify(Group group, Runnable task)
group - Indicates the task group containing the waiting tasks.task - Indicates the task to be executed after all tasks are finished.NullPointerException - Throws this exception if the input parameter task or group is null.void applyDispatch(Consumer<Long> task, long iterations)
Example code:
String[] names = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka",
"David Ferrer","Roger Federer",
"Andy Murray","Tomas Berdych",
"Juan Martin Del Potro"};
int num = atp.length;
TaskDispatcher dispatcher = context.getGlobalTaskDispatcher(TaskPriority.DEFAULT);
// Concurrently dispatches tasks using names in |names|.
dispatcher.applyDispatch((i) ->
{System.out.print(names[i]);}, num);
// The result to be returned depends on thread scheduling of the system.
task - Indicates the task to be executed. This parameter includes all information required for the task
execution.iterations - Indicates the number of times the task is executed. The value must be a positive integer.NullPointerException - Throws this exception if the input parameter task is null.IllegalArgumentException - Throws this exception if the input parameter iterations is 0
or a negative number.