Browse Source

dfs: Remove synchronization in BlockBasedFile#LazyChannel

As explained in 'The "Double-Checked Locking is Broken"
Declaration'[*], Java's memory model does not support double-checked
locking:

 class LazyReadableChannel {
   private ReachableChannel rc = null;

   public ReadableChannel get() {
     if (rc == null) {
       synchronized (this) {
         if (rc == null) {
           rc = new ReadableChannel();
	 }
       }
     }
     return rc;
   }
 }

With JDK 5 and newer, there is a formal memory model that ensures this
works if "rc" is volatile, but it is still not thread-safe without
that.

Fortunately, this ReadableChannelSupplier is never passed between
threads, so it does not need to be thread-safe.  Simplify by removing
the synchronization.

[*] https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

Change-Id: I0698ee6618d734fc129dd4f63fc047c1c17c94a9
Signed-off-by: Jonathan Nieder <jrn@google.com>
stable-5.3
Jonathan Nieder 6 years ago
parent
commit
1131f35cd1
  1. 8
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java

8
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java

@ -213,7 +213,7 @@ abstract class BlockBasedFile {
private final DfsPackDescription desc; private final DfsPackDescription desc;
private final PackExt ext; private final PackExt ext;
private ReadableChannel rc = null; private ReadableChannel rc;
LazyChannel(DfsReader ctx, DfsPackDescription desc, PackExt ext) { LazyChannel(DfsReader ctx, DfsPackDescription desc, PackExt ext) {
this.ctx = ctx; this.ctx = ctx;
@ -224,11 +224,7 @@ abstract class BlockBasedFile {
@Override @Override
public ReadableChannel get() throws IOException { public ReadableChannel get() throws IOException {
if (rc == null) { if (rc == null) {
synchronized (this) { rc = ctx.db.openFile(desc, ext);
if (rc == null) {
rc = ctx.db.openFile(desc, ext);
}
}
} }
return rc; return rc;
} }

Loading…
Cancel
Save