为什么这段ThreadUnsafe类的Go方法不具备线程安全性?
Go() method in ThreadUnsafe is Thread-Unsafe Let’s walk through exactly why this method isn’t safe when multiple threads call it at the same time—there are two critical issues that lead to unpredictable, broken behavior:
1. Race Condition Leading to Division by Zero
The Go() method uses a check-then-act pattern that isn’t atomic. Here’s a step-by-step example of how things can go wrong:
- Thread 1 enters
Go()and checksif (val2 != 0)— let’s sayval2is 5 here, so it passes the check. - Before Thread 1 can execute
System.out.println(val1 / val2), the operating system pauses Thread 1 and switches to Thread 2. - Thread 2 runs the full
Go()method: it checksval2 !=0(still 5), prints the division result, then setsval2 = 0. - Thread 1 resumes execution. It already passed the
ifcheck, so it tries to computeval1 / val2— butval2is now 0, triggering anArithmeticException(division by zero).
This happens because the check and the subsequent division/assignment aren’t treated as a single, indivisible operation. Multiple threads can interfere with each other between these steps.
2. Visibility Issues with Unsynced Static Variables
The val1 and val2 fields are plain static variables with no synchronization or volatile modifier. In a multi-threaded environment:
- When one thread updates
val2, there’s no guarantee that other threads will see this updated value immediately. Threads might cache old values of these variables in their local memory, leading to stale reads. - For example, Thread A sets
val2 = 0, but Thread B might still readval2as its old non-zero value, leading it to attempt the division even thoughval2was already reset.
To fix this, you’d need to wrap the entire logic in a synchronized block (or use other thread-safe constructs like AtomicInteger for the variables) to ensure atomicity and visibility.
内容的提问来源于stack exchange,提问作者JohnBanter

