The N-out-of-M join is a generalization of the discriminator. It is a point in
a process model where M parallel paths converge into one. The subsequent
activity is initiated after N M paths have completed and the respective
termination events have occurred. Completion of all remaining paths is ignored.
As with the discriminator, once all incoming branches have fired, the
join resets itself so that it can be performed again. The N-out-of-M join is
illustrated in Figure 4.16.
A concrete example of the N-out-of-M join is a request for quotation
process, in which quotations are invited from five companies, although the
process can continue after receiving three quotations. Without a dedicated Nout-
of-M join, this business rule would be complex to model, because at design time it is not known which of the companies will respond to the request in
There are variations on this control flow pattern with respect to the time
when the number N of sufficient threads is determined: it can be determined
at design time or at run time. The run time specification of N needs to be
done in an activity instance that is executed before the join.
There might be additional variations in the design time specification of the
N-out-of-M join if it is part of a loop. Design time specification of N could
therefore be taken within the loop, so that different iterations of the loop use
different values N for the number of sufficient threads to complete.
The N-out-of-M join degenerates to an and join if N = M. For N = 1,
however, it does not realize an exclusive or join, because the assumption of
the exclusive or join is not met (only one thread will be activated).
Nor does it realize a multi-merge, because in the multi-merge the completion
of the second and following threads would enable additional instances of
follow-up activities, while the 1-out-of-M join ignores them. The 1-out-of-M
join, however, realizes the discriminator pattern.
An arbitrary cycle is a point in a process model where one or more activities
can be executed repeatedly. An arbitrary cycle is graphically depicted in Figure 4.17. In this example,
a sequence consisting of activity models A, B, and C is iterated. The iteration
is represented by an exclusive or split that decides whether to iterate the cycle
or whether to leave it and continue with activity instance d, associated with
activity model D. In case the loop is iterated, the exclusive or join triggers
another instance associated with activity model A.
As this example shows, arbitrary cycles are expressed with other control
flow patterns, for instance, exclusive or split and exclusive or join. Since these
control flow patterns have been specified already, no additional definitions are
required in order to define the arbitrary cycles pattern.
The problem in this example is that the cycle enters
one of two concurrent branches of an and split whose branches are joined by
The process starts by activitiy instance a, followed by the concurrent execution
of b1 and c1. When c1 completes, the first firing of the multi-merge
spawns off d2. We assume that the loop is not taken, so that e2 is started.
While d2 is still active, b1 terminates, so that the multi-merge creates
another instance of activity model D, namely d3. If the loop is iterated, the
second instance of activity model B is created, i.e., b3 (it holds the same
thread identifier than the previous activity instance).
When b3 terminates, d4 is started, and the loop can be entered again by
spawning off b4. To reset itself, the multi-merge waits for c3. Since the loop
was entered only in one of the concurrent branches, however, c3 does not exist!
Therefore, the multi-merge will not enable new instances of activity model D
when additional instances of activity model B complete.
In this example, after b4 terminates, the process instance will enter a
deadlock, because the multi-merge does not enable a new instance d5. An
event diagram of this execution is depicted in Figure 4.19.
This example shows that the combination of the multi-merge pattern with
loops might cause problematic process behaviour that process designers need
to be aware of to avoid erroneous processes.