added documentation for the task namespace
This commit is contained in:
parent
bfa4231c9d
commit
b18a1dc5b3
|
|
@ -383,6 +383,139 @@ public class TaskExecutorExample {
|
||||||
as scheduled, and potentially recurring, executions.</para>
|
as scheduled, and potentially recurring, executions.</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section id="scheduling-task-namespace">
|
||||||
|
<title>The Task Namespace</title>
|
||||||
|
|
||||||
|
<para>Beginning with Spring 3.0, there is an XML namespace for configuring
|
||||||
|
<interfacename>TaskExecutor</interfacename> and
|
||||||
|
<interfacename>TaskScheduler</interfacename> instances. It also provides a
|
||||||
|
convenient way to configure tasks to be scheduled with a trigger.</para>
|
||||||
|
|
||||||
|
<section id="scheduling-task-namespace-scheduler">
|
||||||
|
<title>The 'scheduler' element</title>
|
||||||
|
<para>The following element will create a
|
||||||
|
<classname>ThreadPoolTaskScheduler</classname> instance with the
|
||||||
|
specified thread pool size.</para>
|
||||||
|
<programlisting language="xml"><![CDATA[<task:scheduler id="scheduler" size="10"/>]]></programlisting>
|
||||||
|
|
||||||
|
<para>The value provided for the "id" attribute will be used as the
|
||||||
|
prefix for thread names within the pool. The 'scheduler' element is
|
||||||
|
relatively straightforward. If you do not provide a 'size' attribute,
|
||||||
|
the default thread pool will only have a single thread. There are no
|
||||||
|
other configuration options for the scheduler.</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="scheduling-task-namespace-executor">
|
||||||
|
<title>The 'executor' element</title>
|
||||||
|
<para>The following will create a
|
||||||
|
<classname>ThreadPoolTaskExecutor</classname> instance:
|
||||||
|
<programlisting language="xml"><![CDATA[<task:executor id="executor" size="10"/>]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>As with the scheduler above, the value provided for the "id"
|
||||||
|
attribute will be used as the prefix for thread names within the pool.
|
||||||
|
As far as the pool size is concerned, the 'executor' element supports
|
||||||
|
more configuration options than the 'scheduler' element. For one thing,
|
||||||
|
the thread pool for a <classname>ThreadPoolTaskExecutor</classname> is
|
||||||
|
itself more configurable. Rather than just a single size, an executor's
|
||||||
|
thread pool may have different values for the <emphasis>core</emphasis>
|
||||||
|
and the <emphasis>max</emphasis> size. If a single value is provided
|
||||||
|
then the executor will have a fixed-size thread pool (the core and max
|
||||||
|
sizes are the same). However, the 'executor' element's 'size' attribute
|
||||||
|
also accepts a range in the form of "m-n".
|
||||||
|
<programlisting language="xml"><![CDATA[<task:executor id="executorWithPoolSizeRange"
|
||||||
|
size="5-25"
|
||||||
|
queue-capacity="100"/>]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>As you can see from that configuration, a 'queue-capacity' value
|
||||||
|
has also been provided. The configuration of the thread pool should
|
||||||
|
also be considered in light of the executor's queue capacity. For the
|
||||||
|
full description of the relationship between pool size and queue
|
||||||
|
capacity, consult the documentation for
|
||||||
|
<ulink url="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html">ThreadPoolExecutor</ulink>.
|
||||||
|
The main idea is that when a task is submitted, the executor will first
|
||||||
|
try to use a free thread if the number of active threads is currently
|
||||||
|
less than the core size. If the core size has been reached, then the
|
||||||
|
task will be added to the queue as long as its capacity has not yet
|
||||||
|
been reached. Only then, if the queue's capacity
|
||||||
|
<emphasis>has</emphasis> been reached, will the executor create a new
|
||||||
|
thread beyond the core size. If the max size has also been reached,
|
||||||
|
then the executor will reject the task.</para>
|
||||||
|
|
||||||
|
<para>By default, the queue is <emphasis>unbounded</emphasis>, but this
|
||||||
|
is rarely the desired configuration, because it can lead to
|
||||||
|
<classname>OutOfMemoryErrors</classname> if enough tasks are added to
|
||||||
|
that queue while all pool threads are busy. Furthermore, if the queue
|
||||||
|
is unbounded, then the max size has no effect at all. Since the
|
||||||
|
executor will always try the queue before creating a new thread beyond
|
||||||
|
the core size, a queue must have a finite capacity for the thread pool
|
||||||
|
to grow beyond the core size (this is why a "fixed-size" pool is the
|
||||||
|
only sensible case when using an unbounded queue).</para>
|
||||||
|
|
||||||
|
<para>In a moment, we will review the effects of the keep-alive setting
|
||||||
|
which adds yet another factor to consider when providing a pool size
|
||||||
|
configuration. First, let's consider the case, as mentioned above, when
|
||||||
|
a task is rejected. By default, when a task is rejected, a thread pool
|
||||||
|
executor will throw a <classname>TaskRejectedException</classname>.
|
||||||
|
However, the rejection policy is actually configurable. The exception
|
||||||
|
is thrown when using the default rejection policy which is the
|
||||||
|
<classname>AbortPolicy</classname> implementation. For applications
|
||||||
|
where some tasks can be skipped under heavy load, either the
|
||||||
|
<classname>DiscardPolicy</classname> or
|
||||||
|
<classname>DiscardOldestPolicy</classname> may be configured instead.
|
||||||
|
Another option that works well for applications that need to throttle
|
||||||
|
the submitted tasks under heavy load is the
|
||||||
|
<classname>CallerRunsPolicy</classname>. Instead of throwing an
|
||||||
|
exception or discarding tasks, that policy will simply force the thread
|
||||||
|
that is calling the submit method to run the task itself. The idea is
|
||||||
|
that such a caller will be busy while running that task and not able to
|
||||||
|
submit other tasks immediately. Therefore it provides a simple way to
|
||||||
|
throttle the incoming load while maintaining the limits of the thread
|
||||||
|
pool and queue. Typically this allows the executor to "catch up" on the
|
||||||
|
tasks it is handling and thereby frees up some capacity on the queue,
|
||||||
|
in the pool, or both. Any of these options can be chosen from an
|
||||||
|
enumeration of values available for the 'rejection-policy' attribute on
|
||||||
|
the 'executor' element.</para>
|
||||||
|
<programlisting language="xml"><![CDATA[<task:executor id="executorWithCallerRunsPolicy"
|
||||||
|
size="5-25"
|
||||||
|
queue-capacity="100"
|
||||||
|
rejection-policy="CALLER_RUNS"/>]]></programlisting>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="scheduling-task-namespace-scheduled-tasks">
|
||||||
|
<title>The 'scheduled-tasks' element</title>
|
||||||
|
|
||||||
|
<para>The most powerful feature of Spring's task namespace is the
|
||||||
|
support for configuring tasks to be scheduled within a Spring
|
||||||
|
Application Context. This follows an approach similar to other
|
||||||
|
"method-invokers" in Spring, such as that provided by the JMS namespace
|
||||||
|
for configuring Message-driven POJOs. Basically a "ref" attribute can
|
||||||
|
point to any Spring-managed object, and the "method" attribute provides
|
||||||
|
the name of a method to be invoked on that object. Here is a simple
|
||||||
|
example.</para>
|
||||||
|
<programlisting language="xml"><![CDATA[<task:scheduled-tasks scheduler="myScheduler">
|
||||||
|
<task:scheduled ref="someObject" method="someMethod" fixed-delay="5000"/>
|
||||||
|
<task:scheduled-tasks/>
|
||||||
|
|
||||||
|
<task:scheduler id="myScheduler" size="10"/>]]></programlisting>
|
||||||
|
|
||||||
|
<para>As you can see, the scheduler is referenced by the outer element,
|
||||||
|
and each individual task includes the configuration of its trigger
|
||||||
|
metadata. In the preceding example, that metadata defines a periodic
|
||||||
|
trigger with a fixed delay. It could also be configured with a
|
||||||
|
"fixed-rate", or for more control, a "cron" attribute could be provided
|
||||||
|
instead. Here's an example featuring these other options.</para>
|
||||||
|
<programlisting language="xml"><![CDATA[<task:scheduled-tasks scheduler="myScheduler">
|
||||||
|
<task:scheduled ref="someObject" method="someMethod" fixed-rate="5000"/>
|
||||||
|
<task:scheduled ref="anotherObject" method="anotherMethod" cron="*/5 * * * * MON-FRI"/>
|
||||||
|
<task:scheduled-tasks/>
|
||||||
|
|
||||||
|
<task:scheduler id="myScheduler" size="10"/>]]></programlisting>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section id="scheduling-quartz">
|
<section id="scheduling-quartz">
|
||||||
<title>Using the OpenSymphony Quartz Scheduler</title>
|
<title>Using the OpenSymphony Quartz Scheduler</title>
|
||||||
<para>Quartz uses <classname>Trigger</classname>, <classname>Job</classname> and
|
<para>Quartz uses <classname>Trigger</classname>, <classname>Job</classname> and
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue