Eclipse Community Forums - RDF feed
https://www.eclipse.org/forums/
Eclipse Community Forumssynchronization on Boolean fields in Eclipse DTP project
https://www.eclipse.org/forums/index.php/mv/msg/188335/597466/#msg_597466
public void refresh() {
synchronized (tablesLoaded) {
if (tablesLoaded.booleanValue()) {
tablesLoaded = Boolean.FALSE;
}
}
synchronized (routinesLoaded) {
if (routinesLoaded.booleanValue()) {
routinesLoaded = Boolean.FALSE;
}
}
synchronized (udtsLoaded) {
if (udtsLoaded.booleanValue()) {
udtsLoaded = Boolean.FALSE;
}
}
RefreshManager.getInstance().referesh(this);
}
You can't synchronize on a field, only on the contents of a field. Since there are only two Boolean objects, all 522 of these synchronization locations are synchronizing on the same two objects, leading to unintended contention. Also, if the field is changed, a second attempt to synchronize on the field will be locking on the other Boolean value, and thus won't provide the intended mutual exclusion. For example, in JDBCStructuredUDT:
public void refresh() {
synchronized (attributesLoaded) {
if (attributesLoaded.booleanValue()) {
attributesLoaded = Boolean.FALSE;
getParameterLoader().clearAttributeDefinitions(
super.getAttributes());
}
}
synchronized (superLoaded) {
if (superLoaded.booleanValue()) {
superLoaded = Boolean.FALSE;
setSuper(null);
}
}
RefreshManager.getInstance().referesh(this);
}
public EList getAttributes() {
synchronized (attributesLoaded) {
if (!attributesLoaded.booleanValue())
loadAttributes();
}
return super.getAttributes();
}
one thread could call refresh, synchronize on Boolean.TRUE, and set attributesLoaded to Boolean.FALSE, and then get context switched out (while still holding the lock on Boolean.TRUE). At that point, another thread could call getAttributes(), synchronize on Boolean.FALSE, and call loadAttributes(), while the other thread is still in the middle of the refresh call.