Skip to content

Commit f39036f

Browse files
authored
Merge pull request #1580 from krmahadevan/krmahadevan-remove-synchronized-locks
Removed sync locks as and where possible.
2 parents cf94d00 + a6a595a commit f39036f

13 files changed

+238
-249
lines changed

src/main/java/org/testng/ClassMethodMap.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package org.testng;
22

3-
import org.testng.collections.Lists;
43
import org.testng.collections.Maps;
54
import org.testng.internal.XmlMethodSelector;
65

6+
import java.util.Collection;
77
import java.util.List;
88
import java.util.Map;
99
import java.util.Set;
10+
import java.util.concurrent.ConcurrentLinkedQueue;
1011

1112
/**
1213
* This class maintains a map of {@code <Class, List<ITestNGMethod>>}.
@@ -17,7 +18,7 @@
1718
* @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
1819
*/
1920
public class ClassMethodMap {
20-
private Map<Object, List<ITestNGMethod>> classMap = Maps.newHashMap();
21+
private Map<Object, Collection<ITestNGMethod>> classMap = Maps.newConcurrentMap();
2122
// These two variables are used throughout the workers to keep track
2223
// of what beforeClass/afterClass methods have been invoked
2324
private Map<ITestClass, Set<Object>> beforeClassMethods = Maps.newHashMap();
@@ -33,9 +34,9 @@ public ClassMethodMap(List<ITestNGMethod> methods, XmlMethodSelector xmlMethodSe
3334
}
3435

3536
Object instance = m.getInstance();
36-
List<ITestNGMethod> l = classMap.get(instance);
37+
Collection<ITestNGMethod> l = classMap.get(instance);
3738
if (l == null) {
38-
l = Lists.newArrayList();
39+
l = new ConcurrentLinkedQueue<>();
3940
classMap.put(instance, l);
4041
}
4142
l.add(m);
@@ -46,8 +47,8 @@ public ClassMethodMap(List<ITestNGMethod> methods, XmlMethodSelector xmlMethodSe
4647
* Remove the method from this map and returns true if it is the last
4748
* of its class.
4849
*/
49-
public synchronized boolean removeAndCheckIfLast(ITestNGMethod m, Object instance) {
50-
List<ITestNGMethod> l = classMap.get(instance);
50+
public boolean removeAndCheckIfLast(ITestNGMethod m, Object instance) {
51+
Collection<ITestNGMethod> l = classMap.get(instance);
5152
if (l == null) {
5253
throw new AssertionError("l should not be null");
5354
}
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
package org.testng;
22

3+
import java.util.concurrent.atomic.AtomicBoolean;
4+
35
/**
46
* A state object that records the status of the suite run. Mainly used to
57
* figure out if there are any @BeforeSuite failures.
68
*/
79
public class SuiteRunState {
810

9-
private boolean m_hasFailures;
11+
private final AtomicBoolean m_hasFailures = new AtomicBoolean();
1012

11-
public synchronized void failed() {
12-
m_hasFailures= true;
13+
public void failed() {
14+
m_hasFailures.set(true);
1315
}
1416

15-
public synchronized boolean isFailed() {
16-
return m_hasFailures;
17+
public boolean isFailed() {
18+
return m_hasFailures.get();
1719
}
1820
}

src/main/java/org/testng/SuiteRunner.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.Map;
3030
import java.util.Set;
3131
import java.util.concurrent.ConcurrentHashMap;
32+
import java.util.concurrent.ConcurrentLinkedQueue;
3233

3334
import com.google.inject.Injector;
3435

@@ -69,7 +70,7 @@ public class SuiteRunner implements ISuite, IInvokedMethodListener {
6970
private Map<Class<? extends IInvokedMethodListener>, IInvokedMethodListener> invokedMethodListeners;
7071

7172
/** The list of all the methods invoked during this run */
72-
private List<IInvokedMethod> invokedMethods = Collections.synchronizedList(Lists.<IInvokedMethod>newArrayList());
73+
private final Collection<IInvokedMethod> invokedMethods = new ConcurrentLinkedQueue<>();
7374

7475
private List<ITestNGMethod> allTestMethods = Lists.newArrayList();
7576
private SuiteRunState suiteState = new SuiteRunState();
@@ -792,7 +793,7 @@ public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
792793

793794
@Override
794795
public List<IInvokedMethod> getAllInvokedMethods() {
795-
return invokedMethods;
796+
return new ArrayList<>(invokedMethods);
796797
}
797798

798799
@Override

src/main/java/org/testng/TestListenerAdapter.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package org.testng;
22

3-
import org.testng.collections.Lists;
43
import org.testng.collections.Objects;
54
import org.testng.internal.IResultListener2;
65

76
import java.util.ArrayList;
8-
import java.util.Collections;
7+
import java.util.Collection;
98
import java.util.List;
9+
import java.util.concurrent.ConcurrentLinkedQueue;
1010

1111

1212
/**
@@ -25,16 +25,15 @@
2525
* @author <a href='mailto:[email protected]'>Alexandru Popescu</a>
2626
*/
2727
public class TestListenerAdapter implements IResultListener2 {
28-
private List<ITestNGMethod> m_allTestMethods =
29-
Collections.synchronizedList(Lists.<ITestNGMethod>newArrayList());
30-
private List<ITestResult> m_passedTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
31-
private List<ITestResult> m_failedTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
32-
private List<ITestResult> m_skippedTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
33-
private List<ITestResult> m_failedButWSPerTests = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
34-
private List<ITestContext> m_testContexts= Collections.synchronizedList(new ArrayList<ITestContext>());
35-
private List<ITestResult> m_failedConfs= Collections.synchronizedList(Lists.<ITestResult>newArrayList());
36-
private List<ITestResult> m_skippedConfs= Collections.synchronizedList(Lists.<ITestResult>newArrayList());
37-
private List<ITestResult> m_passedConfs= Collections.synchronizedList(Lists.<ITestResult>newArrayList());
28+
private Collection<ITestNGMethod> m_allTestMethods = new ConcurrentLinkedQueue<>();
29+
private Collection<ITestResult> m_passedTests = new ConcurrentLinkedQueue<>();
30+
private Collection<ITestResult> m_failedTests = new ConcurrentLinkedQueue<>();
31+
private Collection<ITestResult> m_skippedTests = new ConcurrentLinkedQueue<>();
32+
private Collection<ITestResult> m_failedButWSPerTests = new ConcurrentLinkedQueue<>();
33+
private Collection<ITestContext> m_testContexts = new ConcurrentLinkedQueue<>();
34+
private Collection<ITestResult> m_failedConfs = new ConcurrentLinkedQueue<>();
35+
private Collection<ITestResult> m_skippedConfs = new ConcurrentLinkedQueue<>();
36+
private Collection<ITestResult> m_passedConfs = new ConcurrentLinkedQueue<>();
3837

3938
@Override
4039
public void onTestSuccess(ITestResult tr) {
@@ -138,11 +137,11 @@ public void onTestStart(ITestResult result) {
138137
}
139138

140139
public List<ITestContext> getTestContexts() {
141-
return m_testContexts;
140+
return new ArrayList<>(m_testContexts);
142141
}
143142

144143
public List<ITestResult> getConfigurationFailures() {
145-
return m_failedConfs;
144+
return new ArrayList<>(m_failedConfs);
146145
}
147146

148147
/**
@@ -154,7 +153,7 @@ public void onConfigurationFailure(ITestResult itr) {
154153
}
155154

156155
public List<ITestResult> getConfigurationSkips() {
157-
return m_skippedConfs;
156+
return new ArrayList<>(m_skippedConfs);
158157
}
159158

160159
@Override

src/main/java/org/testng/TestRunner.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.List;
1111
import java.util.Map;
1212
import java.util.Set;
13+
import java.util.concurrent.ConcurrentLinkedQueue;
1314
import java.util.concurrent.LinkedBlockingQueue;
1415
import java.util.concurrent.TimeUnit;
1516

@@ -1407,9 +1408,7 @@ public void addSkippedTest(ITestNGMethod tm, ITestResult tr) {
14071408

14081409
@Override
14091410
public void addInvokedMethod(InvokedMethod im) {
1410-
synchronized(m_invokedMethods) {
1411-
m_invokedMethods.add(im);
1412-
}
1411+
m_invokedMethods.add(im);
14131412
}
14141413

14151414
@Override
@@ -1540,7 +1539,7 @@ void addConfigurationListener(IConfigurationListener icl) {
15401539
// Listeners
15411540
/////
15421541

1543-
private final List<InvokedMethod> m_invokedMethods = Lists.newArrayList();
1542+
private final Collection<InvokedMethod> m_invokedMethods = new ConcurrentLinkedQueue<>();
15441543

15451544
private void dumpInvokedMethods() {
15461545
System.out.println("===== Invoked methods");
@@ -1561,12 +1560,10 @@ else if (im.isConfigurationMethod()) {
15611560

15621561
public List<ITestNGMethod> getInvokedMethods() {
15631562
List<ITestNGMethod> result= Lists.newArrayList();
1564-
synchronized(m_invokedMethods) {
1565-
for (IInvokedMethod im : m_invokedMethods) {
1566-
ITestNGMethod tm= im.getTestMethod();
1567-
tm.setDate(im.getDate());
1568-
result.add(tm);
1569-
}
1563+
for (IInvokedMethod im : m_invokedMethods) {
1564+
ITestNGMethod tm = im.getTestMethod();
1565+
tm.setDate(im.getDate());
1566+
result.add(tm);
15701567
}
15711568

15721569
return result;

src/main/java/org/testng/internal/BaseTestMethod.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.testng.internal;
22

33
import java.lang.reflect.Method;
4+
import java.util.ArrayList;
45
import java.util.Arrays;
56
import java.util.Collection;
67
import java.util.Collections;
@@ -9,6 +10,7 @@
910
import java.util.Map;
1011
import java.util.Set;
1112
import java.util.concurrent.Callable;
13+
import java.util.concurrent.ConcurrentLinkedQueue;
1214
import java.util.concurrent.atomic.AtomicInteger;
1315
import java.util.regex.Pattern;
1416

@@ -64,7 +66,7 @@ public abstract class BaseTestMethod implements ITestNGMethod {
6466
private long m_invocationTimeOut = 0L;
6567

6668
private List<Integer> m_invocationNumbers = Lists.newArrayList();
67-
private final List<Integer> m_failedInvocationNumbers = Collections.synchronizedList(Lists.<Integer>newArrayList());
69+
private final Collection<Integer> m_failedInvocationNumbers = new ConcurrentLinkedQueue<>();
6870
private long m_timeOut = 0;
6971

7072
private boolean m_ignoreMissingDependencies;
@@ -742,7 +744,7 @@ public void setInvocationNumbers(List<Integer> numbers) {
742744

743745
@Override
744746
public List<Integer> getFailedInvocationNumbers() {
745-
return m_failedInvocationNumbers;
747+
return new ArrayList<>(m_failedInvocationNumbers);
746748
}
747749

748750
@Override

src/main/java/org/testng/internal/ConfigurationGroupMethods.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Collection;
99
import java.util.List;
1010
import java.util.Map;
11+
import java.util.concurrent.ConcurrentHashMap;
1112

1213
/**
1314
* This class wraps access to beforeGroups and afterGroups methods,
@@ -28,15 +29,15 @@ public class ConfigurationGroupMethods {
2829
private final ITestNGMethod[] m_allMethods;
2930

3031
/**A map that returns the last method belonging to the given group */
31-
private Map<String, List<ITestNGMethod>> m_afterGroupsMap= null;
32+
private Map<String, List<ITestNGMethod>> m_afterGroupsMap = null;
3233

3334
public ConfigurationGroupMethods(ITestNGMethod[] allMethods,
3435
Map<String, List<ITestNGMethod>> beforeGroupsMethods,
3536
Map<String, List<ITestNGMethod>> afterGroupsMethods)
3637
{
37-
m_allMethods= allMethods;
38-
m_beforeGroupsMethods= beforeGroupsMethods;
39-
m_afterGroupsMethods= afterGroupsMethods;
38+
m_allMethods = allMethods;
39+
m_beforeGroupsMethods = new ConcurrentHashMap<>(beforeGroupsMethods);
40+
m_afterGroupsMethods = new ConcurrentHashMap<>(afterGroupsMethods);
4041
}
4142

4243
public ITestNGMethod[] getAllTestMethods() {
@@ -56,7 +57,7 @@ public Map<String, List<ITestNGMethod>> getAfterGroupsMethods() {
5657
* This method is used to figure out when is the right time to invoke
5758
* afterGroups methods.
5859
*/
59-
public synchronized boolean isLastMethodForGroup(String group, ITestNGMethod method) {
60+
public boolean isLastMethodForGroup(String group, ITestNGMethod method) {
6061

6162
// If we have more invocation to do, this is not the last one yet
6263
if(method.hasMoreInvocation()) {
@@ -65,7 +66,11 @@ public synchronized boolean isLastMethodForGroup(String group, ITestNGMethod met
6566

6667
// Lazy initialization since we might never be called
6768
if(m_afterGroupsMap == null) {
68-
m_afterGroupsMap= initializeAfterGroupsMap();
69+
synchronized (this) {
70+
if (m_afterGroupsMap == null) {
71+
m_afterGroupsMap = initializeAfterGroupsMap();
72+
}
73+
}
6974
}
7075

7176
List<ITestNGMethod> methodsInGroup= m_afterGroupsMap.get(group);
@@ -81,8 +86,8 @@ public synchronized boolean isLastMethodForGroup(String group, ITestNGMethod met
8186

8287
}
8388

84-
private synchronized Map<String, List<ITestNGMethod>> initializeAfterGroupsMap() {
85-
Map<String, List<ITestNGMethod>> result= Maps.newHashMap();
89+
private Map<String, List<ITestNGMethod>> initializeAfterGroupsMap() {
90+
Map<String, List<ITestNGMethod>> result= Maps.newConcurrentMap();
8691
for(ITestNGMethod m : m_allMethods) {
8792
String[] groups= m.getGroups();
8893
for(String g : groups) {
@@ -98,7 +103,7 @@ private synchronized Map<String, List<ITestNGMethod>> initializeAfterGroupsMap()
98103
return result;
99104
}
100105

101-
public synchronized void removeBeforeMethod(String group, ITestNGMethod method) {
106+
public void removeBeforeMethod(String group, ITestNGMethod method) {
102107
List<ITestNGMethod> methods= m_beforeGroupsMethods.get(group);
103108
if(methods != null) {
104109
Object success= methods.remove(method);
@@ -115,22 +120,22 @@ private void log(String string) {
115120
Utils.log("ConfigurationGroupMethods", 2, string);
116121
}
117122

118-
synchronized public Map<String, List<ITestNGMethod>> getBeforeGroupsMap() {
123+
public Map<String, List<ITestNGMethod>> getBeforeGroupsMap() {
119124
return m_beforeGroupsMethods;
120125
}
121126

122-
synchronized public Map<String, List<ITestNGMethod>> getAfterGroupsMap() {
127+
public Map<String, List<ITestNGMethod>> getAfterGroupsMap() {
123128
return m_afterGroupsMethods;
124129
}
125130

126-
synchronized public void removeBeforeGroups(String[] groups) {
131+
public void removeBeforeGroups(String[] groups) {
127132
for(String group : groups) {
128133
// log("Removing before group " + group);
129134
m_beforeGroupsMethods.remove(group);
130135
}
131136
}
132137

133-
synchronized public void removeAfterGroups(Collection<String> groups) {
138+
public void removeAfterGroups(Collection<String> groups) {
134139
for(String group : groups) {
135140
// log("Removing before group " + group);
136141
m_afterGroupsMethods.remove(group);

src/main/java/org/testng/internal/TestMethodWorker.java

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -186,32 +186,31 @@ protected void invokeAfterClassMethods(ITestClass testClass, IMethodInstance mi)
186186
//
187187
List<Object> invokeInstances= Lists.newArrayList();
188188
ITestNGMethod tm= mi.getMethod();
189-
if (m_classMethodMap.removeAndCheckIfLast(tm, mi.getInstance())) {
190-
Map<ITestClass, Set<Object>> invokedAfterClassMethods
191-
= m_classMethodMap.getInvokedAfterClassMethods();
192-
synchronized(invokedAfterClassMethods) {
193-
Set<Object> instances = invokedAfterClassMethods.get(testClass);
194-
if(null == instances) {
195-
instances= new HashSet<>();
196-
invokedAfterClassMethods.put(testClass, instances);
197-
}
198-
Object inst = mi.getInstance();
199-
if(!instances.contains(inst)) {
200-
invokeInstances.add(inst);
201-
}
202-
}
189+
boolean removalSuccessful = m_classMethodMap.removeAndCheckIfLast(tm, mi.getInstance());
190+
if (!removalSuccessful) {
191+
return;
192+
}
193+
Map<ITestClass, Set<Object>> invokedAfterClassMethods = m_classMethodMap.getInvokedAfterClassMethods();
194+
Set<Object> instances = invokedAfterClassMethods.get(testClass);
195+
if (null == instances) {
196+
instances = new HashSet<>();
197+
invokedAfterClassMethods.put(testClass, instances);
198+
}
199+
Object inst = mi.getInstance();
200+
if (!instances.contains(inst)) {
201+
invokeInstances.add(inst);
202+
}
203203

204-
for (IClassListener listener : m_listeners) {
205-
listener.onAfterClass(testClass);
206-
}
207-
for(Object inst: invokeInstances) {
208-
m_invoker.invokeConfigurations(testClass,
209-
testClass.getAfterClassMethods(),
210-
m_suite,
211-
m_parameters,
212-
null, /* no parameter values */
213-
inst);
214-
}
204+
for (IClassListener listener : m_listeners) {
205+
listener.onAfterClass(testClass);
206+
}
207+
for (Object invokeInstance : invokeInstances) {
208+
m_invoker.invokeConfigurations(testClass,
209+
testClass.getAfterClassMethods(),
210+
m_suite,
211+
m_parameters,
212+
null, /* no parameter values */
213+
invokeInstance);
215214
}
216215
}
217216

0 commit comments

Comments
 (0)