Skip to content

Commit a7efa0a

Browse files
committed
Secon pass - handle multi-lock cases
1 parent 24d3cd2 commit a7efa0a

File tree

8 files changed

+422
-171
lines changed

8 files changed

+422
-171
lines changed

spring-integration-core/src/main/java/org/springframework/integration/expression/ReloadableResourceBundleExpressionSource.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@
2525
import java.util.Locale;
2626
import java.util.Map;
2727
import java.util.Properties;
28+
import java.util.concurrent.locks.Lock;
29+
import java.util.concurrent.locks.ReentrantLock;
2830

2931
import org.apache.commons.logging.Log;
3032
import org.apache.commons.logging.LogFactory;
@@ -80,16 +82,22 @@ public class ReloadableResourceBundleExpressionSource implements ExpressionSourc
8082
*/
8183
private final Map<String, Map<Locale, List<String>>> cachedFilenames = new HashMap<>();
8284

85+
private final Lock cachedFilenamesMonitor = new ReentrantLock();
86+
8387
/**
8488
* Cache to hold already loaded properties per filename.
8589
*/
8690
private final Map<String, PropertiesHolder> cachedProperties = new HashMap<>();
8791

92+
private final Lock cachedPropertiesMonitor = new ReentrantLock();
93+
8894
/**
8995
* Cache to hold merged loaded properties per locale.
9096
*/
9197
private final Map<Locale, PropertiesHolder> cachedMergedProperties = new HashMap<>();
9298

99+
private final Lock cachedMergedPropertiesMonitor = new ReentrantLock();
100+
93101
private final ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
94102

95103
private String[] basenames = {};
@@ -282,7 +290,8 @@ private String getExpressionString(String key, Locale locale) {
282290
* cached forever.
283291
*/
284292
private PropertiesHolder getMergedProperties(Locale locale) {
285-
synchronized (this.cachedMergedProperties) {
293+
this.cachedMergedPropertiesMonitor.lock();
294+
try {
286295
PropertiesHolder mergedHolder = this.cachedMergedProperties.get(locale);
287296
if (mergedHolder != null) {
288297
return mergedHolder;
@@ -303,6 +312,9 @@ private PropertiesHolder getMergedProperties(Locale locale) {
303312
this.cachedMergedProperties.put(locale, mergedHolder);
304313
return mergedHolder;
305314
}
315+
finally {
316+
this.cachedMergedPropertiesMonitor.unlock();
317+
}
306318
}
307319

308320
/**
@@ -316,7 +328,8 @@ private PropertiesHolder getMergedProperties(Locale locale) {
316328
* @see #calculateFilenamesForLocale
317329
*/
318330
private List<String> calculateAllFilenames(String basename, Locale locale) {
319-
synchronized (this.cachedFilenames) {
331+
this.cachedFilenamesMonitor.lock();
332+
try {
320333
Map<Locale, List<String>> localeMap = this.cachedFilenames.get(basename);
321334
if (localeMap != null) {
322335
List<String> filenames = localeMap.get(locale);
@@ -345,6 +358,9 @@ private List<String> calculateAllFilenames(String basename, Locale locale) {
345358
}
346359
return filenames;
347360
}
361+
finally {
362+
this.cachedFilenamesMonitor.unlock();
363+
}
348364
}
349365

350366
/**
@@ -392,7 +408,8 @@ private List<String> calculateFilenamesForLocale(String basename, Locale locale)
392408
* @return the current PropertiesHolder for the bundle
393409
*/
394410
private PropertiesHolder getProperties(String filename) {
395-
synchronized (this.cachedProperties) {
411+
this.cachedPropertiesMonitor.lock();
412+
try {
396413
PropertiesHolder propHolder = this.cachedProperties.get(filename);
397414
if (propHolder != null &&
398415
(propHolder.getRefreshTimestamp() < 0 ||
@@ -401,6 +418,9 @@ private PropertiesHolder getProperties(String filename) {
401418
}
402419
return refreshProperties(filename, propHolder);
403420
}
421+
finally {
422+
this.cachedPropertiesMonitor.unlock();
423+
}
404424
}
405425

406426
/**
@@ -539,12 +559,21 @@ private void loadFromProperties(Resource resource, String filename, InputStream
539559
*/
540560
public void clearCache() {
541561
LOGGER.debug("Clearing entire resource bundle cache");
542-
synchronized (this.cachedProperties) {
562+
this.cachedPropertiesMonitor.lock();
563+
try {
543564
this.cachedProperties.clear();
544565
}
545-
synchronized (this.cachedMergedProperties) {
566+
finally {
567+
this.cachedPropertiesMonitor.unlock();
568+
}
569+
570+
this.cachedMergedPropertiesMonitor.lock();
571+
try {
546572
this.cachedMergedProperties.clear();
547573
}
574+
finally {
575+
this.cachedMergedPropertiesMonitor.unlock();
576+
}
548577
}
549578

550579
@Override

spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/AbstractConnectionFactory.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
8080

8181
private final Map<String, TcpConnectionSupport> connections = new ConcurrentHashMap<>();
8282

83+
private final Lock connectionsMonitor = new ReentrantLock();
84+
8385
private final BlockingQueue<PendingIO> delayedReads = new LinkedBlockingQueue<>();
8486

8587
private final List<TcpSender> senders = Collections.synchronizedList(new ArrayList<>());
@@ -568,7 +570,8 @@ protected Executor getTaskExecutor() {
568570
@Override
569571
public void stop() {
570572
this.active = false;
571-
synchronized (this.connections) {
573+
this.connectionsMonitor.lock();
574+
try {
572575
Iterator<Entry<String, TcpConnectionSupport>> iterator = this.connections.entrySet().iterator();
573576
while (iterator.hasNext()) {
574577
TcpConnectionSupport connection = iterator.next().getValue();
@@ -582,6 +585,10 @@ public void stop() {
582585
}
583586
}
584587
}
588+
finally {
589+
this.connectionsMonitor.unlock();
590+
}
591+
585592
this.lifecycleMonitor.lock();
586593
try {
587594
if (this.privateExecutor) {
@@ -860,22 +867,27 @@ protected void doAccept(final Selector selector, ServerSocketChannel server, lon
860867
}
861868

862869
protected void addConnection(TcpConnectionSupport connection) {
863-
synchronized (this.connections) {
870+
this.connectionsMonitor.lock();
871+
try {
864872
if (!this.active) {
865873
connection.close();
866874
return;
867875
}
868876
this.connections.put(connection.getConnectionId(), connection);
869877
logger.debug(() -> getComponentName() + ": Added new connection: " + connection.getConnectionId());
870878
}
879+
finally {
880+
this.connectionsMonitor.unlock();
881+
}
871882
}
872883

873884
/**
874885
* Cleans up this.connections by removing any closed connections.
875886
* @return a list of open connection ids.
876887
*/
877888
private List<String> removeClosedConnectionsAndReturnOpenConnectionIds() {
878-
synchronized (this.connections) {
889+
this.connectionsMonitor.lock();
890+
try {
879891
List<String> openConnectionIds = new ArrayList<>();
880892
Iterator<Entry<String, TcpConnectionSupport>> iterator = this.connections.entrySet().iterator();
881893
while (iterator.hasNext()) {
@@ -899,6 +911,9 @@ private List<String> removeClosedConnectionsAndReturnOpenConnectionIds() {
899911
}
900912
return openConnectionIds;
901913
}
914+
finally {
915+
this.connectionsMonitor.unlock();
916+
}
902917
}
903918

904919
/**
@@ -959,7 +974,8 @@ public List<String> getOpenConnectionIds() {
959974
public boolean closeConnection(String connectionId) {
960975
Assert.notNull(connectionId, "'connectionId' to close must not be null");
961976
// closed connections are removed from #connections in #harvestClosedConnections()
962-
synchronized (this.connections) {
977+
this.connectionsMonitor.lock();
978+
try {
963979
boolean closed = false;
964980
TcpConnectionSupport connection = this.connections.remove(connectionId);
965981
if (connection != null) {
@@ -975,6 +991,9 @@ public boolean closeConnection(String connectionId) {
975991
}
976992
return closed;
977993
}
994+
finally {
995+
this.connectionsMonitor.unlock();
996+
}
978997
}
979998

980999
@Override

0 commit comments

Comments
 (0)