Skip to content

Commit a962a5f

Browse files
committed
Double-checked locking to reduce overhead of lazy-initialization
The synchronization on the methods setPlatform and basicGetPlatform have been removed as well, as it is not sensible to have a synchronized setter without a synchronized getter. Such synchronization would in any case not prevent usage of old retrieved platforms. To prevent such cases, where the retrieved platform is cached locally, consumers need to register as listeners for notifications.
1 parent db67361 commit a962a5f

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/layered/DefaultXtextTargetPlatformManager.java

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,37 +35,48 @@ public class DefaultXtextTargetPlatformManager implements IXtextTargetPlatformMa
3535
private IXtextTargetPlatformFactory platformFactory;
3636

3737
/** The current platform. */
38-
private IXtextTargetPlatform platform;
38+
private volatile IXtextTargetPlatform platform; // NOPMD (volatile)
3939

4040
/** Flag indicating that the target platform manager is shutting down. */
4141
private volatile boolean shutdownInProgress; // NOPMD (volatile)
4242

43+
private final Object lock = new Object();
44+
4345
protected IXtextTargetPlatformFactory getPlatformFactory() {
4446
return platformFactory;
4547
}
4648

4749
@Override
48-
public synchronized IXtextTargetPlatform getPlatform() {
49-
ensureLoaded();
50-
return platform;
50+
public IXtextTargetPlatform getPlatform() {
51+
return ensureLoaded();
5152
}
5253

5354
/**
5455
* Return the platform, but without making sure it's loaded. Just return the raw attribute.
5556
*
5657
* @return the current target platform, or null if none set.
5758
*/
58-
protected synchronized IXtextTargetPlatform basicGetPlatform() {
59+
protected IXtextTargetPlatform basicGetPlatform() {
5960
return platform;
6061
}
6162

6263
/**
6364
* Make sure the platform is loaded.
65+
*
66+
* @returns the loaded platform
6467
*/
65-
protected void ensureLoaded() {
66-
if (platform == null) {
67-
load(new NullProgressMonitor());
68+
protected IXtextTargetPlatform ensureLoaded() {
69+
IXtextTargetPlatform localRef = platform; // access volatile field only once when initialized
70+
if (localRef == null) {
71+
synchronized (this) {
72+
localRef = platform;
73+
if (localRef == null) {
74+
load(new NullProgressMonitor());
75+
localRef = platform;
76+
}
77+
}
6878
}
79+
return localRef;
6980
}
7081

7182
/**
@@ -156,19 +167,21 @@ public void setPlatform(final IXtextTargetPlatform newPlatform) {
156167
* @param mustRebuild
157168
* whether a rebuild is required in any case.
158169
*/
159-
public synchronized void setPlatform(final IXtextTargetPlatform newPlatform, final Collection<IResourceDescription.Delta> deltas, final boolean mustRebuild) {
160-
IXtextTargetPlatform oldPlatform = platform;
170+
public void setPlatform(final IXtextTargetPlatform newPlatform, final Collection<IResourceDescription.Delta> deltas, final boolean mustRebuild) {
171+
synchronized (lock) {
172+
IXtextTargetPlatform oldPlatform = platform;
161173

162-
if (oldPlatform == null && newPlatform == null) {
163-
return; // may occur during initialization...
164-
}
174+
if (oldPlatform == null && newPlatform == null) {
175+
return; // may occur during initialization...
176+
}
165177

166-
if (newPlatform == null) {
167-
this.platform = new NullXtextTargetPlatform();
168-
} else {
169-
this.platform = newPlatform;
178+
if (newPlatform == null) {
179+
this.platform = new NullXtextTargetPlatform();
180+
} else {
181+
this.platform = newPlatform;
182+
}
183+
notifyListeners(platform, deltas, mustRebuild);
170184
}
171-
notifyListeners(platform, deltas, mustRebuild);
172185
}
173186

174187
}

0 commit comments

Comments
 (0)