When I started designing, the ideas of synchronization were explained to me. Always double or triple sample signals from external sources, or from other clock domains. As it was explained to me, each flop reduced the chances of metastability by a very large factor. 2 samples were considered enough to lower the chances of metastaibility to almost nothing. 3 flops were even better.
As I got more experience, I got used to only using 2 flops to move between clock domains, or to bring an external signal in. But what was really going on?
There are 2 reasons for synchronization flops.
1. Metastable oscillation. This requires an explanation of metastability.
Metastability is a state whereby a flip-flop will sample an input signal on a clock edge, but the input signal is in a state of transition. This is a common situation when sampling from another clock domain or from an external signal. When a flip-flop samples an input signal that is not stable high or stable low, the flip-flop's output is undefined. Suffice it to say that an undefined output means that the output does not rise or fall as would be expected. The output wavers and takes a while to settle in one state or another.
A metastable flop will settle after a while. The assumed time it takes for a metastable flop to settle is a complete clock period. While a flop-flop is metastable, any flop sampling the metastable flop's output could also go metastable.
A second synchronization flop guarantees a full clock period of time for the output of the first metastable synchronization flop to settle and arrive at the second synchronization flop. As a rule of synchronization, there can be no combinatorial logic between the first and second flops.
Metastable oscillations can occur if there is a path whereby metastability can loop around. This can occur with a single flop, or with a sequence of flops. The simplest example of metastable oscillation can be with one flop. A single flop whose input comes from a mux that has a select signal to choose between an external signal and the flop's own output is prone to metastable oscillation. The flop can be used to sample an input signal, and then hold that value using the select of the input mux. But since the output of this flop is driven back to it's input using a mux, there may not be enough time for the output to settle before it is sampled back into itself.
2. Indeterminate input. When an output from another clock domain or an external signal is input into multiple flops at the same time, there is no guarantee that each flop will settle with the same input value. There are also the risks of metastability propagating through the sampling flops.