Junction points are static conditional branches, while choice points are dynamic conditional branches. Static conditional branches mean that all the guards of transitions chained by junction points (terminating at a choice point or a state) are evaluated prior to taking the first transition. Only if an enabled path exists is the transition fired and their effects executed. For example, consider a case where you have:
When the event for t1 arrives, both t1's guard and t2's guard must evaluate to true prior to firing t1 and executing the effect of t1 followed by the effect of t2. If you start with x=1 and y=5, t1 never fires. If you have x=1 && y=4, t1 fires, and when you arrive in State2, y equals 5 and x equals 2.
Compare this with a case when you use a choice point instead of a junction point:
In this case, only t1's guard (x==1) must to evaluate to true before firing t1 and executing its effect. When the behavior arrives at the choice point, it evaluates the outgoing transition guards to determine the path to take, using the unguarded ('else') branch if no guarded path evaluates to true.
Junction points can be used before, or after a choice point, or both. All guards for transitions compounded by junction points must evaluate to true for that path to be considered enabled. For example, in the following case, x==1 && y < 5 must be true for t1 to fire. Once fired, y and x increment. The behavior reaches the choice point and z<5 && y>=5 must evaluate to true to transition to S2.
Note: t3's effect is not executed prior to the evaluation. If both of these guard conditions are not true, the system transitions to the 'Default' state. Otherwise, t3's effect and t4's effect are executed and the system transitions to S2.
One benefit of using junction points is code reuse in subclasses. For example:
You can set up some pre- and post-conditions or logic while enabling the main work to be written in specialized capsules. Using this type of pattern, only the 'to redefine' transition needs to be redefined to have an effect or guard. The rest of the logic is inherited and reused.
Following is what the UML2 standard says about junction and choice points:
Junction vertices are semantic-free vertices that are used to chain together multiple transitions. The junctions are used to construct compound transition paths between states. For example, a junction can be used to converge multiple incoming transitions into a single outgoing transition representing a shared transition path (this is known as a merge).
Conversely, junctions can be used to split an incoming transition into multiple outgoing transition segments with different guard conditions. This realizes a static conditional branch. (In this case, outgoing transitions whose guard conditions evaluate to false are disabled. A predefined guard denoted “else” might be defined for, at most, one outgoing transition. This transition is enabled if all the guards labeling the other transitions are false.) Static conditional branches are distinct from dynamic conditional branches that are realized by choice vertices.
Choice vertices, which, when reached, result in the dynamic evaluation of the guards of the triggers of its outgoing transitions. This realizes a dynamic conditional branch. A dynamic conditional branch enables splitting of transitions into multiple outgoing paths, such that the decision on which path to take might be a function of the results of prior actions performed in the same run-to-completion step. If more than one of the guards evaluates to true, an arbitrary guard is selected. If none of the guards evaluates to true, the model is considered ill-formed. (To avoid an ill-formed model, define one outgoing transition with the predefined “else” guard for every choice vertex.) Choice vertices should be distinguished from static branch points that are based on junction points, as described previously.
For more information on this topic, see the document Choice and Junction Points