单例模式之生产实践

本文探讨了单例模式的基本概念及其在多线程环境中的应用问题。通过具体示例说明了当单例模式被不当使用时可能导致的数据混乱问题,并提出了解决方案——将全局变量改为局部变量以确保线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

以前从课本上也学过单例模式,个人认为单例模式是所有模式中最简单的模式之一了。

课本上是这么说的:单例模式(singleton)顾名思义,就是一个类只有一个实例。就是说在线程运行当中该类只创建一个实例对象,举个例子,有个类PolicyVO,每当程序运行时并且线程A调用到要创建这个对象是,只创建一个对象,这时候线程A还没有结束;那么,这时候如果再过来一个线程B,恰好又要调用这个类中的方法,从正常上来讲会自己单独再创建一个该类对象,但是现在由于采用了单例模式,线程B就会直接引用这个对象了,那么该对象中的所有的成员变量其实还是线程A创建PolicyVO对象时的值,这样从逻辑上来讲,就已经产生错误了,最后导致的结果就是数据混乱。

那么解决方法是什么呢?对于一个项目来说如果把这个改成非单例模式,修改成本太高。

其实只要把下面标红的一些全局变量改为局部变量。为什么呢?

外部每次在调用AllocDSImpl.PremARAPVO(…)这个方法的时候,方法内引用的都是全局变量policyVO,线程B和线程A共享该变量;如果把policyVO改为局部变量,那么外部每次调用该方法都会单独创建该policyVO不会相互影响,这个就是局部变量和全局变量的区别。

(有说的不对不足的地方欢迎指出)

错误代码示例及修改实例…

public class AllocDSImpl extends GenericDSimplements AllocService, ARAPCst {

 protected boolean terminate = false;

 protected AppUser user = null;

 protected Long operatorId = null;

 protected Long payeeAddressId = null;

 protected Date allocDate = null;

 protected Integer product_id = null;

 protected Long masterItemId = null; // Added on 2007-5-22, for master

 

 protected BigDecimal authLimitAmount = new BigDecimal(20000);

  protected PolicyCIVO policyVO;

 protected ARAPService arAPDS;

  //added by matt.zhou

  //payment requisition will be added to baseline by EP

 public AllocServiceHelper allocServiceHelper;

。。。。。。。。

。。。。。。。。

。。。。。。。。

。。。。。。。。

。。。。。。。。

。。。。。。。。

。。。。。。。。

。。。。。。。。

。。。。。。。。

。。。。。。。。

rotected PremARAPVO generateARAP(AppUseruser, Date allocDate,

     PolicyCIVO policyVO, Long payeeId, Long accountType, Integer feeType,

     BigDecimal feeAmount, Integer payMode, Integer serviceId, Long agentId,

     String withDrawType, Integer feeStatus, CSCIVO csVO, Long payeeAccount)

     throws GenericException {

   Long changeId = csVO.getMasterChgId();

   Long policyChgId = csVO.getPolicyChgId();

   PremARAPVO premARAPVO = new PremARAPVO();

   premARAPVO.setAccountType(accountType);

   premARAPVO.setAgentId(agentId);

   premARAPVO.setBillDate(allocDate); // Date of bill

//premARAPVO.setBranchId(policyVO.getBranchId());

//修改成

PolicyCIVO policyVO = new PolicyCIVO();

policyVO = ………..//调用方法获取policyVO

//然后获取branchId,

premARAPVO.setBranchId(policyVO.getBranchId());

   premARAPVO.setProductId(this.product_id);

premARAPVO.setItemId(this.masterItemId);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值