JCIP-6-Task Execution

7 篇文章 0 订阅

6-Task Execution
6.1-Executing tasks in threads
6.1.1. Executing Tasks Sequentially
6.1.2. Explicitly Creating Threads for Tasks
6.1.3. Disadvantages of Unbounded Thread Creation
Thread lifecycle overhead. Thread creation and teardown are not free
Resource consumption. When there are more runnable
threads than available processors, threads sit idle.Having many idle threads can tie up a lot of memory.
Stability. it is far easier to structure your program to avoid hitting this limit.Up to a certain point, more threads can improve throughput, but beyond that point creating more threads just slows
down your application
On 32-bit machines, a major limiting factor is address space for thread stacks. Each thread maintains two execution stacks, one for Java code
and one for native code.
6.2-The Executor framework
6.2.1. Example: Web Server Using Executor
java.util.concurrent provides a flexible thread
pool implementation as part of the Executor framework.
It provides a standard means of decoupling task
submission from task execution, describing tasks with Runnable.
Using
an Executor is usually the easiest path to implementing a producer-consumer design in your application.
6.2.2. Execution Policies
An execution policy specifies the “what, where, when, and
how” of task execution
Whenever you see code of the form:new Thread(runnable).start() seriously consider replacing it with the use
of an Executor.
6.2.3. Thread Pools
newFixedThreadPool
keep the pool size constant (adding new threads if a thread dies
newCachedThreadPool
add new threads when demand increases
newSingleThreadExecutor
replacing it if it dies unexpectedly.
newScheduledThreadPool
A fixed-size thread pool that supports delayed and periodic task execution
6.2.4. Executor Lifecycle
But the JVM can’t exit until all the (non-daemon) threads have terminated,so failing to
shut down an Executor could prevent the JVM from exiting.
The lifecycle implied by ExecutorService has three states: running, shutting down, and terminated. The shutdownNow method initiates an abrupt shutdown: it attempts to cancel outstanding tasks and
does not start any tasks that are queued but not begun.
You can wait for an ExecutorService to reach the terminated state with awaitTermination, It is common to follow shutdown immediately by awaitTermination, creating
the effect of synchronously shutting down the ExecutorService.
6.2.5. Delayed and Periodic Tasks
The Timer facility manages the execution of deferred and periodic tasks. However, Timer has some drawbacks, and ScheduledThreadPoolExecutor should be thought of as its
replacement.
Timer does have support for scheduling based on absolute, not relative time, so that tasks can be sensitive to changes in the system clock;
ScheduledThreadPoolExecutor supports only relative time.
A Timer creates only a single thread for executing timer tasks.Scheduled
thread pools address this limitation by letting you provide multiple threads for executing deferred and periodic tasks.
so an unchecked exception thrown from a TimerTask terminates the timer thread. Timer
also doesn’t resurrect the thread in this situation; instead, it erroneously assumes the entire Timer was cancelled. ScheduledThreadPoolExecutor deals
properly with ill-behaved tasks; there is little reason to use Timer in Java 5.0 or later.
DelayQueue, a BlockingQueue implementation that provides the scheduling functionality of
ScheduledThreadPoolExecutor.
6.3-Finding exploitable parallelism
6.3.1. Example: Sequential Page Renderer
6.3.2. Result-bearing Tasks: Callable and Future
Runnable is a fairly limiting abstraction; run
cannot return a value or throw checked exceptions.
For these types of tasks, Callable is a better abstraction: it expects that the main
entry point, call, will return a value and anticipates that it might throw an exception.
To express a non-value-returning task with Callable, use Callable.
a task executed by an Executor has four phases: created, submitted,
started, and completed.
Future represents the lifecycle of a task and provides methods to test whether the task has completed or been
cancelled, retrieve its result, and cancel the task.
Future.get:It returns immediately or
throws an Exception if the task has already completed, but if not it blocks until the task completes.If get throws ExecutionException, the underlying exception can be retrieved with
getCause.
Future.get deals with two possible problems: that the task encountered an Exception, or the thread
calling get was interrupted before the results were available.
6.3.3. Example: Page Renderer with Future
6.3.4. Limitations of Parallelizing Heterogeneous Tasks
6.3.5. CompletionService: Executor Meets BlockingQueue
CompletionService combines the functionality of an Executor and a BlockingQueue. You can submit Callable tasks
to it for execution and use the queue-like methods take and poll to retrieve completed results, packaged as Futures,
as they become available. ExecutorCompletionService implements CompletionService, delegating the computation
to an Executor.
When a task is submitted, it is wrapped with a QueueingFuture, a subclass of FutureTask that overrides
done to place the result on the BlockingQueue,
6.3.6. Example: Page Renderer with CompletionService
6.3.7. Placing Time Limits on Tasks
The timed version of Future.get supports this
requirement: it returns as soon as the result is ready, but throws TimeoutException if the result is not ready within the
timeout period.
if a timed get completes with a TimeoutException, you can cancel the task through the
Future.
6.3.8. Example: A Travel Reservations Portal
The invokeAll method takes a collection of tasks and returns a collection of Futures. The two collections have
identical structures; invokeAll adds the Futures to the returned collection in the order imposed by the task collection’s
iterator, thus allowing the caller to associate a Future with the Callable it represents.
Summary
The
Executor framework permits you to decouple task submission from execution policy and supports a rich variety of
execution policies; whenever you find yourself creating threads to perform tasks, consider using an Executor instead.
To maximize the benefit of decomposing an application into tasks, you must identify sensible task boundaries.
Summary
6.1-Executing tasks in threads
6.1.1. Executing Tasks Sequentially
6.1.2. Explicitly Creating Threads for Tasks
6.1.3. Disadvantages of Unbounded Thread Creation
Thread lifecycle overhead. Thread creation and teardown are not free
Resource consumption. When there are more runnable
threads than available processors, threads sit idle.Having many idle threads can tie up a lot of memory.
Stability. it is far easier to structure your program to avoid hitting this limit.Up to a certain point, more threads can improve throughput, but beyond that point creating more threads just slows
down your application
On 32-bit machines, a major limiting factor is address space for thread stacks. Each thread maintains two execution stacks, one for Java code
and one for native code.
6.2-The Executor framework
6.2.1. Example: Web Server Using Executor
java.util.concurrent provides a flexible thread
pool implementation as part of the Executor framework.
It provides a standard means of decoupling task
submission from task execution, describing tasks with Runnable.
Using
an Executor is usually the easiest path to implementing a producer-consumer design in your application.
6.2.2. Execution Policies
An execution policy specifies the “what, where, when, and
how” of task execution
Whenever you see code of the form:new Thread(runnable).start() seriously consider replacing it with the use
of an Executor.
6.2.3. Thread Pools
newFixedThreadPool
keep the pool size constant (adding new threads if a thread dies
newCachedThreadPool
add new threads when demand increases
newSingleThreadExecutor
replacing it if it dies unexpectedly.
newScheduledThreadPool
A fixed-size thread pool that supports delayed and periodic task execution
6.2.4. Executor Lifecycle
But the JVM can’t exit until all the (non-daemon) threads have terminated,so failing to
shut down an Executor could prevent the JVM from exiting.
The lifecycle implied by ExecutorService has three states: running, shutting down, and terminated. The shutdownNow method initiates an abrupt shutdown: it attempts to cancel outstanding tasks and
does not start any tasks that are queued but not begun.
You can wait for an ExecutorService to reach the terminated state with awaitTermination, It is common to follow shutdown immediately by awaitTermination, creating
the effect of synchronously shutting down the ExecutorService.
6.2.5. Delayed and Periodic Tasks
The Timer facility manages the execution of deferred and periodic tasks. However, Timer has some drawbacks, and ScheduledThreadPoolExecutor should be thought of as its
replacement.
Timer does have support for scheduling based on absolute, not relative time, so that tasks can be sensitive to changes in the system clock;
ScheduledThreadPoolExecutor supports only relative time.
A Timer creates only a single thread for executing timer tasks.Scheduled
thread pools address this limitation by letting you provide multiple threads for executing deferred and periodic tasks.
so an unchecked exception thrown from a TimerTask terminates the timer thread. Timer
also doesn’t resurrect the thread in this situation; instead, it erroneously assumes the entire Timer was cancelled. ScheduledThreadPoolExecutor deals
properly with ill-behaved tasks; there is little reason to use Timer in Java 5.0 or later.
DelayQueue, a BlockingQueue implementation that provides the scheduling functionality of
ScheduledThreadPoolExecutor.
6.3-Finding exploitable parallelism
6.3.1. Example: Sequential Page Renderer
6.3.2. Result-bearing Tasks: Callable and Future
Runnable is a fairly limiting abstraction; run
cannot return a value or throw checked exceptions.
For these types of tasks, Callable is a better abstraction: it expects that the main
entry point, call, will return a value and anticipates that it might throw an exception.
To express a non-value-returning task with Callable, use Callable.
a task executed by an Executor has four phases: created, submitted,
started, and completed.
Future represents the lifecycle of a task and provides methods to test whether the task has completed or been
cancelled, retrieve its result, and cancel the task.
Future.get:It returns immediately or
throws an Exception if the task has already completed, but if not it blocks until the task completes.If get throws ExecutionException, the underlying exception can be retrieved with
getCause.
Future.get deals with two possible problems: that the task encountered an Exception, or the thread
calling get was interrupted before the results were available.
6.3.3. Example: Page Renderer with Future
6.3.4. Limitations of Parallelizing Heterogeneous Tasks
6.3.5. CompletionService: Executor Meets BlockingQueue
CompletionService combines the functionality of an Executor and a BlockingQueue. You can submit Callable tasks
to it for execution and use the queue-like methods take and poll to retrieve completed results, packaged as Futures,
as they become available. ExecutorCompletionService implements CompletionService, delegating the computation
to an Executor.
When a task is submitted, it is wrapped with a QueueingFuture, a subclass of FutureTask that overrides
done to place the result on the BlockingQueue,
6.3.6. Example: Page Renderer with CompletionService
6.3.7. Placing Time Limits on Tasks
The timed version of Future.get supports this
requirement: it returns as soon as the result is ready, but throws TimeoutException if the result is not ready within the
timeout period.
if a timed get completes with a TimeoutException, you can cancel the task through the
Future.
6.3.8. Example: A Travel Reservations Portal
The invokeAll method takes a collection of tasks and returns a collection of Futures. The two collections have
identical structures; invokeAll adds the Futures to the returned collection in the order imposed by the task collection’s
iterator, thus allowing the caller to associate a Future with the Callable it represents.
Summary
The
Executor framework permits you to decouple task submission from execution policy and supports a rich variety of
execution policies; whenever you find yourself creating threads to perform tasks, consider using an Executor instead.
To maximize the benefit of decomposing an application into tasks, you must identify sensible task boundaries.
Summary

DISSIDIA思维导图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值