FindBug发现的Java内存模型相关bug

165 篇文章 3 订阅
文章讨论了在多线程环境下,非同步和非volatile字段的延迟初始化可能导致的问题。Java内存模型可能导致指令重排序,使得对象未完全初始化就被其他线程访问。为解决此问题,文章提供了使用volatile关键字和双重检查锁定模式的修正方案,确保线程安全的延迟初始化。
摘要由CSDN通过智能技术生成

This method contains an unsynchronized lazy initialization of a non-volatile static field. Because the compiler or processor may reorder instructions, threads are not guaranteed to see a completely initialized object, if the method can be called by multiple threads. You can make the field volatile to correct the problem. For more information, see the Java Memory Model web site.

此方法包含非易失性静态字段的非同步延迟初始化。因为编译器或处理器可能会对指令进行重新排序,所以如果可以由多个线程调用该方法,则不能保证线程能够看到完全初始化的对象。您可以使字段不稳定以更正问题。有关更多信息,请参阅Java内存模型网站。

The Java Memory Model

参考:  https://blog.csdn.net/wylsde_zjy/article/details/84881596

错误代码:

// 单线程版本[没有问题] class Foo {
 private Helper helper = null;
 public Helper getHelper() {
 if (helper == null)
  helper = new Helper(); 
return helper;
 } // other functions and members... 
}
 // 多线程版本 --很多东西可能会出错 
class Foo2 { 
private Helper helper = null; 
public synchronized Helper getHelper() { 
if (helper == null) 
helper = new Helper(); 
return helper; 
} // other functions and members... 
} 
// 多线程版本--双重检查锁定习惯用法,在优化编译器或共享内存多处理器的存在下不起作用。 
class Foo3 { 
private Helper helper = null;
public Helper getHelper() { 
if (helper == null) // findbugs报错 
synchronized (this) {// 同步 
if (helper == null) 
helper = new Helper(); 
} 
return helper; 
} // other functions and members...
 }

改正:

// 使用volatile
 class Foo5 {
 private volatile Helper helper = null;
 public Helper getHelper() {
 if (helper == null) { 
synchronized (this) {
 if (helper == null)
 helper = new Helper(); 
} 
}
 return helper; 
}
}

----------------------------------------------------

引起问题的代码:

                              

	public static void register(String dataSourceToolType, DataSourceBuilder builder) {
		if (map == null) map = new ConcurrentHashMap<>();
		map.put(dataSourceToolType.toLowerCase(), builder);
	}

改正后的代码:  

	private static volatile Map<String, DataSourceBuilder> map = null;
	private static byte[] lock=new byte[0];

	private DataSourceBuilderFactory() {}

	public static void register(String dataSourceToolType, DataSourceBuilder builder) {
		if (map == null) {
			synchronized (lock) {
				map = new ConcurrentHashMap<>();
			}
		}
		map.put(dataSourceToolType.toLowerCase(), builder);
	}

源码地址:

GitHub - automvc/bee-ext: Extension Tools for Bee ! Easy and Useful ! A ORM Support JDBC,Cassandra,Mongodb,Sharding,Android,HarmonyOS. 关于Bee的扩展工具集.

https://github.com/automvc/bee-ext

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值