Browse Source

fix lock bug

Looly 6 years ago
parent
commit
010f0554ae

+ 1 - 0
CHANGELOG.md

@@ -14,6 +14,7 @@
 * 【core】        修复DateUtil.offset导致的时区错误问题(issue#I1294O@Gitee)
 * 【core】        修复RuntimeUtil.exec重载导致的问题(issue#544@Github)
 * 【db】          修复StatementUtil.getGeneratedKeys返回主键数量不足问题
+* 【db】          修复锁的问题(issue#546@Github)
 
 -------------------------------------------------------------------------------------------------------------
 

+ 1 - 1
hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java

@@ -75,7 +75,7 @@ public class ConverterRegistry implements Serializable{
 	/** 默认类型转换器 */
 	private Map<Type, Converter<?>> defaultConverterMap;
 	/** 用户自定义类型转换器 */
-	private Map<Type, Converter<?>> customConverterMap;
+	private volatile Map<Type, Converter<?>> customConverterMap;
 
 	/** 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 */
 	private static class SingletonHolder {

+ 15 - 14
hutool-db/src/main/java/cn/hutool/db/ds/GlobalDSFactory.java

@@ -5,10 +5,9 @@ import cn.hutool.log.StaticLog;
 /**
  * 全局的数据源工厂<br>
  * 一般情况下,一个应用默认只使用一种数据库连接池,因此维护一个全局的数据源工厂类减少判断连接池类型造成的性能浪费
- * 
+ *
  * @author looly
  * @since 4.0.2
- *
  */
 public class GlobalDSFactory {
 
@@ -36,7 +35,7 @@ public class GlobalDSFactory {
 	 * 获取默认的数据源工厂,读取默认数据库配置文件<br>
 	 * 此处使用懒加载模式,在第一次调用此方法时才创建默认数据源工厂<br>
 	 * 如果想自定义全局的数据源工厂,请在第一次调用此方法前调用{@link #set(DSFactory)} 方法自行定义
-	 * 
+	 *
 	 * @return 当前使用的数据源工厂
 	 */
 	public static DSFactory get() {
@@ -54,26 +53,28 @@ public class GlobalDSFactory {
 	 * 设置全局的数据源工厂<br>
 	 * 在项目中存在多个连接池库的情况下,我们希望使用低优先级的库时使用此方法自定义之<br>
 	 * 重新定义全局的数据源工厂此方法可在以下两种情况下调用:
-	 * 
+	 *
 	 * <pre>
 	 * 1. 在get方法调用前调用此方法来自定义全局的数据源工厂
 	 * 2. 替换已存在的全局数据源工厂,当已存在时会自动关闭
 	 * </pre>
-	 * 
+	 *
 	 * @param customDSFactory 自定义数据源工厂
 	 * @return 自定义的数据源工厂
 	 */
-	synchronized public static DSFactory set(DSFactory customDSFactory) {
-		if (null != factory) {
-			if (factory.equals(customDSFactory)) {
-				return factory;// 数据源工厂不变时返回原数据源工厂
+	public static DSFactory set(DSFactory customDSFactory) {
+		synchronized (lock) {
+			if (null != factory) {
+				if (factory.equals(customDSFactory)) {
+					return factory;// 数据源工厂不变时返回原数据源工厂
+				}
+				// 自定义数据源工厂前关闭之前的数据源
+				factory.destroy();
 			}
-			// 自定义数据源工厂前关闭之前的数据源
-			factory.destroy();
-		}
 
-		StaticLog.debug("Custom use [{}] datasource.", customDSFactory.dataSourceName);
-		factory = customDSFactory;
+			StaticLog.debug("Custom use [{}] DataSource.", customDSFactory.dataSourceName);
+			factory = customDSFactory;
+		}
 		return factory;
 	}
 }