If an outcome is deterministic, then that outcome is not in any way dependent on chance. The heads-or-tails outcome of flipping a coin where both sides are heads is deterministic because we know that no matter how we flip it, it will always come up heads.
This is how we want our programs to be – deterministic. Unless we explicitly include an element of randomness, we want our programs to behave the same way each time we run them.
A singly-threaded program is inherently deterministic. When the program has a single thread, the order in which those tasks are executed is the same every time.
In multi-threaded programs, since the tasks are executed concurrently, the sequential order of tasks is not guaranteed. In other words, they are non-deterministic and to some extent, random. When this randomness affects the behavior of the program, we have what is known as a race condition.
Consider the following situation depicted in the animation to the right. We have a program with the expression x = 3
and two threads. The job of thread_one
is to execute x = x * 2
and the job of thread two
is to execute x = x + 1
.
In case 1, thread_one
executes before thread_two
and by the end of our program’s execution, x
has a value of 7
.
In case 2, thread_two
executes before thread_one
which means x
will equal 8
by the end of execution.
In the following exercises, we will look at another example of a race condition as well as ways we can synchronize our programs in order to avoid them.
Instructions
Click Next when you’re ready to move on to the next exercise.