Because, as you say, i++ is not a singular operation. Normally we would say, it's not
atomic. It really consists of 3 operations:
1. Read the current value of i
2. Add 1 to that value
3. Write the new value of i
If these steps occur simultaneously in different threads, strange things can happen.
Thread A: 1. read i = 0;
Thread A: 2. add 1 - Thread A's local copy of i is now 1
Thread B: 1. read i = 0;
Thread B: 2. add 1 - Thread B's local copy of i is now 1
Thread B: 3. write the new value of i = 1
Thread A: 3. write the new value of i = 1
That's probably what happened in the run you're asking about.