Reputation: 2134
I think I have a fairly firm grasp on using the synchronized
keyword to prevent inconsistencies between threads in java, but I don't fully understand what happens if you don't use that keyword.
Say for instance that I have a field accessed/modified by two threads:
private String sharedString = "";
class OneThread extends Thread {
private Boolean mRunning = false;
public OneThread() {}
public synchronized setRunning(Boolean b) {
mRunning = b;
}
@Override
public void run() {
while (mRunning) {
// read or write to shared string
sharedString = "text from thread 1";
System.out.println("String seen from thread 1: " + sharedString);
super.run();
}
}
}
class AnotherThread extends Thread {
private Boolean mRunning = false;
public AnotherThread() {}
public synchronized setRunning(Boolean b) {
mRunning = b;
}
@Override
public void run() {
while (mRunning) {
// read or write to shared string
sharedString = "text from thread 2";
System.out.println("String seen from thread 2: " + sharedString);
super.run();
}
}
}
Since both of these threads are accessing and modifying the field sharedString
without using the synchronized keyword, I would expect inconsistencies. What I am wondering is what actually happens though. While debugging, I have stepped carefully through both threads in situations like this and noticed that even while one thread is paused, it's state can be "sticky".
For the sake of the above example, suppose both threads are paused in the debugger. If I step through one of the threads and leave the other paused, I would expect it would operate like a single threaded application. Yet, many times right after modifying the field, the next line that accesses it retrieves the "wrong" value (a value inconsistent with what it was just modified to).
I know that this code is not good.. but I am asking the question because I'm hoping someone could provide an answer that gives some insight into what actually happens in the virtual machine when multi-threaded applications are implemented poorly. Does the thread who's field modification attempt was unsuccessful have any effect at all?
If after poorly implementing multi-threaded code we are simply in the realm of "undefined" behavior, and there is no value in learning about this behavior, I'm ok with that.. just a multi-threading noob trying to understand what I observe in the debugger.
Upvotes: 0
Views: 263
Reputation: 28638
This is due to another critical function of synchronization across threads in Java: preventing data staleness. As part of the Java Memory Model, a Java thread may cache values for shared data. There is no guarantee that a thread will ever see updates made by another thread unless either the shared mutable data is accessed in synchronized blocks or it is marked as volatile. See here for more information.
Upvotes: 4
Reputation: 326
There's really no way for the printout to be "wrong" if there is no other thread that can change the shared value (as would be the case if there are really only 2 threads and one is definitely paused). Can you by chance provide the code that "kicks off" these 2 threads (i.e. your main)?
Upvotes: 0