When you call str.intern()
you indeed get access to the internal instance of string, i.e. if this sting already in cache you get reference to this instance.
When you say:
String s = .... /* anything */
you create variable that contains yet another reference to the same string.
Therefore when you say
s = null;
you just put null
to that reference. It does not affect the object itself. So, it will be removed by GC if GC decides to remove it. You still can use the source object (that one that was written right to the assignment operator) for synchronization. Surely synchronized(id.intern())
looks OK. Although I have no idea why do you want to do this.
BTW re-using objects that have functional meaning in your program for synchronization is a very bad pattern. Think about the following scenario. You are using id.intern()
for syncghronization. This means that if you ID is for example foo
and somebody in other part of the program says
String s = 'foo'
he gets access to the same object because string literals are cached.
Now if in other part of the program the following code is written:
String s = 'foo';
.....
synchronized(s) {
s.notify();
}
and in you wrote in your part of the code
synchronized(id.intern()) {
id.wait();
}
probably your wait()
will exit! Such unexpected behavior of the program is very hard to debug. Therefore better practice is to use special objects for locks.