Singleton Pattern 单态模式

本文详细解析了SingletonPattern单态模式的实现方式及其在多线程环境下的挑战,通过分析双检查锁模式的原理与误用,揭示了其潜在风险。进一步介绍了正确的实现方法,确保在多线程环境下SingletonPattern的实例唯一性,同时讨论了不同虚拟机对同步方法执行效率的影响。
Singleton Pattern 单态模式。

这个模式较简单,就是为了保证一个类只有一个实例,用一个入口来获取该实例。

例子如下(代码来自维基):

class Foo {
private static Helper helper = null;
private Foo(){}
public static Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}

// other functions and members...
}

由于构造方法设为了私有,所以其它类无法使用new 来生成该类实例,只有通过
该类自己提供的方法来获取实例。这个获取实例的方法通总是使用第一次创建的
实例而保证其它类总是使用同一个实例。

本来很简单,但是在多线程情况下则会有些麻烦。两个线程都有可能执行到了第
6行,这样就有可能创建2个实例。过程如下(线程1简称为T1,线程2 简称T2):

T1 5 (5代表第5行)
T2 5
T1 6
T1 7 (线程1返回一个实例)
T2 6
T2 7 (线程2返回另一个实例)

这样就破坏了实例唯一性。如果这两个实例状态不会变化,倒也无所谓,就是多
花点内存养两个对象。但如果这两个实例涉及到计数器等状态变化,就埋下了隐患。

解决办法是加上同步关键字,如下:

    public static synchronized Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}


问题是解决了,但效率却降低了。因为每次获取实例都会执行同步运算。实际上
没必要。一旦实例创建并返回,以后再获取实例就不会执行第6行。为了发生几率
很小的事件而每次同步的方法,代价太大了。

不同虚拟机对同步方法的执行效率不同,早期虚拟机执行同步效率非常的低。现
在改进了很多,但进入线程体、离开线程体、加锁、解锁这些步骤仍然耗费性能。

所以,后来发明了双检查锁模式。(Double-Checked Locking Pattern)。在
《DesignPatternsExplained》一书中,作者专门分析了这种方法的优势,并给出
了代码。代码如下:

class USTax {
private static USTax instance;
private synchronized USTax(){};
public static USTax getlnstance () {
if(instance== null)
instance= new USTax();
return instance;
}
}


不想,书上印错了,这让很多人包括我迷惑良久。后来书本经过更正,变为如下形式,

class USTax {
private static USTax instance;
private USTax(){};
public static synchronized void doSyn(){
if(instance== null){
instance= new USTax();
instance.setSomething();}//这句是我加的,为方便接下来的解释。
}
public static USTax getlnstance () {
if(instance== null)
doSyn();
return instance;
}
}


到此,算是万事大吉了。不料这种双重检查模式仍然有问题,并不能解决多线程
的问题。由于这本书的广泛流传,这种模式也广为人知。当这种模式的错误之处
被发现后,很快就出现了对这种模式广泛的讨伐之声。可见,影响越大,一旦有
错,被讨伐的力度也就越大。

我们以上面这段代码为例,看看问题是怎样产生的,

T1 10 (线程1执行到第10行)
T1 5
T1 6
T2 10
T2 12

也就是说,线程1还没有完全构造完这个对象(还没有执行第7行),线程2就返回
这个半成品对象了。所以,这种谬种流传的 Double-Checked Locking Pattern也
就寿终正寝,不能再被使用了。

那这种多线程出现的问题该怎么做呢,解决方法也很简单,如下即可,

class USTax {
private static USTax instance = new USTax();
private USTax(){};
public static synchronized void doSyn(){
if(instance== null)
instance= new USTax();
}
public static USTax getlnstance () {
return instance;
}
}
内容概要:本文介绍了基于贝叶斯优化的CNN-LSTM混合神经网络在时间序列预测中的应用,并提供了完整的Matlab代码实现。该模型结合了卷积神经网络(CNN)在特征提取方面的优势与长短期记忆网络(LSTM)在处理时序依赖问题上的强大能力,形成一种高效的混合预测架构。通过贝叶斯优化算法自动调参,提升了模型的预测精度与泛化能力,适用于风电、光伏、负荷、交通流等多种复杂非线性系统的预测任务。文中还展示了模型训练流程、参数优化机制及实际预测效果分析,突出其在科研与工程应用中的实用性。; 适合人群:具备一定机器学习基基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)础和Matlab编程经验的高校研究生、科研人员及从事预测建模的工程技术人员,尤其适合关注深度学习与智能优化算法结合应用的研究者。; 使用场景及目标:①解决各类时间序列预测问题,如能源出力预测、电力负荷预测、环境数据预测等;②学习如何将CNN-LSTM模型与贝叶斯优化相结合,提升模型性能;③掌握Matlab环境下深度学习模型搭建与超参数自动优化的技术路线。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注贝叶斯优化模块与混合神经网络结构的设计逻辑,通过调整数据集和参数加深对模型工作机制的理解,同时可将其框架迁移至其他预测场景中验证效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值