60 lines
1.5 KiB
Plaintext
60 lines
1.5 KiB
Plaintext
Synchronizing on a class field synchronizes not on the field itself, but on the object assigned to it. So synchronizing on a non-``++final++`` field makes it possible for the field's value to change while a thread is in a block synchronized on the old value. That would allow a second thread, synchronized on the new value, to enter the block at the same time.
|
|
|
|
|
|
The story is very similar for synchronizing on parameters; two different threads running the method in parallel could pass two different object instances in to the method as parameters, completely undermining the synchronization.
|
|
|
|
|
|
== Noncompliant Code Example
|
|
|
|
[source,text]
|
|
----
|
|
private String color = "red";
|
|
|
|
private void doSomething(){
|
|
synchronized(color) { // Noncompliant; lock is actually on object instance "red" referred to by the color variable
|
|
//...
|
|
color = "green"; // other threads now allowed into this block
|
|
// ...
|
|
}
|
|
synchronized(new Object()) { // Noncompliant this is a no-op.
|
|
// ...
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
== Compliant Solution
|
|
|
|
[source,text]
|
|
----
|
|
private String color = "red";
|
|
private final Object lockObj = new Object();
|
|
|
|
private void doSomething(){
|
|
synchronized(lockObj) {
|
|
//...
|
|
color = "green";
|
|
// ...
|
|
}
|
|
}
|
|
----
|
|
|
|
include::see.adoc[]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
include::message.adoc[]
|
|
|
|
include::highlighting.adoc[]
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::../comments-and-links.adoc[]
|
|
endif::env-github,rspecator-view[]
|