s isn't a String object; it's a String
variable. It
points to a String. It can point to different String objects at different times. The line 's += "time"' means to add the String pointed to by s to the String "time", then store the result back in the variable s. The String object "good" is unchanged, but you don't have a variable that points to it anymore.
The sample code you're showing is really a crazy mess; personally I think whoever wrote this sample question ought to have to crawl 20 paces on their knees through a room full of marbles. But in any case, look at the parameter name in the routine "piggy". The local parameter name takes precedence over the static variable name, so that the variable that is assigned to in piggy() is the parameter, not the static variable. That's why we don't see the "wiggy" part.
As far as the run() method goes: start() gets a
thread moving, but run() hasn't necessarily even been called yet by the time start returns; so when the main thread prints out the value of the static variable -- which will indeed be reassigned from run() -- the reassignment hasn't happened yet; i.e., the assignments to sName are made (usually!) after the println() call.
(Actually in the code you show, you've got the line that does the assignment commented out -- I suspect that's just a typo).
It's
possible, if highly unlikely, that you could see the strings you expected with the numbers on them, but 999,999 times out of a million, the println() will happen before the first assignment is made. Even if it doesn't, there are other issues with communication between threads that I haven't even addressed here.