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 <[email protected]>
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() {

Reply via email to