If both P0 and P1 are executed, and each is executed only once, it is true that P0 will enter the critical section first, exclusively, before P1 does.
In term of Java Memory Model, this program is correctly synchronized, because all inter-thread actions are volatile reads and writes. Therefore the program is sequentially consistent, easy to analyze.
Or, more specifically, all volatile reads and writes are in a total order (that's consistent with the programming order); this order will guarantee the mutual exclusiveness of critical sections.
However, there is a serious problem here. If P1 arrives first, it must wait for P0, no matter how late P0 arrives. This is quite unfair. And, if P0 is not executed, P1 cannot advance. And, If P0 is executed and P1 is not, P0 cannot enter the critical section again (it must wait for P1 to reset the turn). This locking mechanism only allows a strict P0-P1-P0-P1-... sequence (unless that is exactly what's desired)
To solve this problem, there are Dekker's algorithm, Peterson's algorithm, etc. See this post - https://cs.stackexchange.com/a/12632