This attribute may be set on the xsl:for-each instruction. The value must be an integer. When this attribute is used
with Saxon-EE, the items selected by the
select expression of the instruction
are processed in parallel, using the specified number of threads.
The threads are allocated on a round-robin basis: for example if
is specified, then the first item will be processed using thread 1, the second using thread
2, the third using thread 3, the fourth using thread 1 again, and so on. These threads are
in addition to the main control thread (so there will be 4 threads in total). Before firing
off the processing of the third item, the control thread will read off the results of
processing the first item, and send them to the destination of the
It is possible to specify
saxon:threads="1". In this case all the items in the
input will be processed sequentially, but asynchronously with the thread that reads the
items in the input sequence.
Processing using multiple threads can take advantage of multi-core CPUs.
However, there is an overhead, in that the results of processing each item in the input need
to be buffered. The overhead of coordinating multiple threads is proportionally higher if
the per-item processing cost is low, while the overhead of buffering is proportionally
higher if the amount of data produced when each item is processed is high. Multi-threading
therefore works best when the body of the
xsl:for-each instruction performs a
large amount of computation but produces a small amount of output.
It is possible to combine multi-threading with sorting. However, the input is first read and sorted synchronously, and the items in the sorted sequence are then processed in parallel.
The effect of using extensions that have side-effects (including saxon:assign) in a multi-threaded loop is undefined (and probably fatal).
Multi-threaded processing is available only with Saxon-EE. The attribute
saxon:threads is ignored with a warning if Saxon-EE is not in use. Under
Saxon-EE it may also be disabled using the configuration property
processing is also disabled if code is compiled with tracing enabled, for example by using
-T option on the command line or by using an IDE debugger (this is because
otherwise, the trace events would be hopelessly intermingled).
With multi-threaded processing, the output of different xsl:message instructions may appear in an unpredictable
order. However, Saxon ensures that the
xsl:message instruction is atomic, so
one message will be completed before another starts. The same is true of the output from the
trace() function call.