Skip to content

Commit 3dc1ca7

Browse files
committed
Improve locking on JavacCompiler
- the code synchonizes on the CopyOnWriteArrayList which is a concurrent collection - the double check locking pattern is badly written and does not actually double checks
1 parent b7cc076 commit 3dc1ca7

File tree

1 file changed

+17
-20
lines changed
  • plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac

1 file changed

+17
-20
lines changed

plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java

+17-20
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@
5858
import java.net.URLClassLoader;
5959
import java.util.ArrayList;
6060
import java.util.Arrays;
61+
import java.util.Deque;
6162
import java.util.List;
6263
import java.util.Map;
6364
import java.util.NoSuchElementException;
6465
import java.util.Properties;
6566
import java.util.StringTokenizer;
66-
import java.util.concurrent.CopyOnWriteArrayList;
67+
import java.util.concurrent.ConcurrentLinkedDeque;
6768

6869
import org.codehaus.plexus.compiler.AbstractCompiler;
6970
import org.codehaus.plexus.compiler.CompilerConfiguration;
@@ -102,9 +103,9 @@ public class JavacCompiler extends AbstractCompiler {
102103

103104
private static final String JAVAC_CLASSNAME = "com.sun.tools.javac.Main";
104105

105-
private static volatile Class<?> JAVAC_CLASS;
106+
private volatile Class<?> javacClass;
106107

107-
private final List<Class<?>> javaccClasses = new CopyOnWriteArrayList<>();
108+
private final Deque<Class<?>> javacClasses = new ConcurrentLinkedDeque<>();
108109

109110
@Inject
110111
private InProcessCompiler inProcessCompiler;
@@ -955,7 +956,7 @@ private static String getJavacExecutable() throws IOException {
955956
private void releaseJavaccClass(Class<?> javaccClass, CompilerConfiguration compilerConfiguration) {
956957
if (compilerConfiguration.getCompilerReuseStrategy()
957958
== CompilerConfiguration.CompilerReuseStrategy.ReuseCreated) {
958-
javaccClasses.add(javaccClass);
959+
javacClasses.add(javaccClass);
959960
}
960961
}
961962

@@ -966,32 +967,28 @@ private void releaseJavaccClass(Class<?> javaccClass, CompilerConfiguration comp
966967
* @throws CompilerException if the class has not been found.
967968
*/
968969
private Class<?> getJavacClass(CompilerConfiguration compilerConfiguration) throws CompilerException {
969-
Class<?> c = null;
970+
Class<?> c;
970971
switch (compilerConfiguration.getCompilerReuseStrategy()) {
971972
case AlwaysNew:
972973
return createJavacClass();
973974
case ReuseCreated:
974-
synchronized (javaccClasses) {
975-
if (javaccClasses.size() > 0) {
976-
c = javaccClasses.get(0);
977-
javaccClasses.remove(c);
978-
return c;
979-
}
975+
c = javacClasses.poll();
976+
if (c == null) {
977+
c = createJavacClass();
980978
}
981-
c = createJavacClass();
982979
return c;
983980
case ReuseSame:
984981
default:
985-
c = JavacCompiler.JAVAC_CLASS;
986-
if (c != null) {
987-
return c;
988-
}
989-
synchronized (JavacCompiler.LOCK) {
990-
if (c == null) {
991-
JavacCompiler.JAVAC_CLASS = c = createJavacClass();
982+
c = javacClass;
983+
if (c == null) {
984+
synchronized (this) {
985+
c = javacClass;
986+
if (c == null) {
987+
javacClass = c = createJavacClass();
988+
}
992989
}
993-
return c;
994990
}
991+
return c;
995992
}
996993
}
997994

0 commit comments

Comments
 (0)