You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by wu...@apache.org on 2023/05/30 06:04:43 UTC
[shardingsphere] branch master updated: Avoid ConcurrentHashMap recursive update in ShardingSphereServiceLoader.getServiceInstances (#24558)
This is an automated email from the ASF dual-hosted git repository.
wuweijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new de53bbbcd2d Avoid ConcurrentHashMap recursive update in ShardingSphereServiceLoader.getServiceInstances (#24558)
de53bbbcd2d is described below
commit de53bbbcd2d5aa930ee408e4bc5119efe7041f50
Author: Hongsheng Zhong <zh...@apache.org>
AuthorDate: Tue May 30 14:04:35 2023 +0800
Avoid ConcurrentHashMap recursive update in ShardingSphereServiceLoader.getServiceInstances (#24558)
* Replace computeIfAbsent in getServiceInstances to avoid possible ConcurrentHashMap recursive update
* Lazy load service instances to reduce locked time in getServiceInstances
* Revert "Lazy load service instances to reduce locked time in getServiceInstances"
This reverts commit 1352bd49462a8bf8ac77563958357aa4157e01d2.
* Reduce lock range
---
.../util/spi/ShardingSphereServiceLoader.java | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/infra/util/src/main/java/org/apache/shardingsphere/infra/util/spi/ShardingSphereServiceLoader.java b/infra/util/src/main/java/org/apache/shardingsphere/infra/util/spi/ShardingSphereServiceLoader.java
index f52278f429e..a774defebe6 100644
--- a/infra/util/src/main/java/org/apache/shardingsphere/infra/util/spi/ShardingSphereServiceLoader.java
+++ b/infra/util/src/main/java/org/apache/shardingsphere/infra/util/spi/ShardingSphereServiceLoader.java
@@ -37,11 +37,21 @@ public final class ShardingSphereServiceLoader<T> {
private static final Map<Class<?>, ShardingSphereServiceLoader<?>> LOADERS = new ConcurrentHashMap<>();
+ private static final int LOAD_LOCKS_COUNT = 16;
+
+ private static final Object[] LOAD_LOCKS = new Object[LOAD_LOCKS_COUNT];
+
private final Class<T> serviceInterface;
@Getter
private final Collection<T> services;
+ static {
+ for (int i = 0; i < LOAD_LOCKS_COUNT; i++) {
+ LOAD_LOCKS[i] = new Object();
+ }
+ }
+
private ShardingSphereServiceLoader(final Class<T> serviceInterface) {
this.serviceInterface = serviceInterface;
validate();
@@ -72,7 +82,17 @@ public final class ShardingSphereServiceLoader<T> {
@SuppressWarnings("unchecked")
public static <T> Collection<T> getServiceInstances(final Class<T> serviceInterface) {
ShardingSphereServiceLoader<?> result = LOADERS.get(serviceInterface);
- return (Collection<T>) (null != result ? result.getServiceInstances() : LOADERS.computeIfAbsent(serviceInterface, ShardingSphereServiceLoader::new).getServiceInstances());
+ if (null != result) {
+ return (Collection<T>) result.getServiceInstances();
+ }
+ synchronized (LOAD_LOCKS[serviceInterface.hashCode() % LOAD_LOCKS_COUNT]) {
+ result = LOADERS.get(serviceInterface);
+ if (null == result) {
+ result = new ShardingSphereServiceLoader<>(serviceInterface);
+ LOADERS.put(serviceInterface, result);
+ }
+ }
+ return (Collection<T>) result.getServiceInstances();
}
private Collection<T> getServiceInstances() {