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
threads="3" 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
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 option
xslt/@allowMultiThreading='false' in the configuration file.
Multi-threaded processing is also disabled if code is compiled with tracing enabled, for example by using the -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.