博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于单例模式的心结
阅读量:6698 次
发布时间:2019-06-25

本文共 1914 字,大约阅读时间需要 6 分钟。

  今天重构公司的代码,看到有一个单例的对象,在整个系统中到处都存在调用它的身影,因为我们这个项目会在应用服务器(server)第一次启动的时候加载数据库中的代码表(为什么要先加载,因为这个项目采用的是C/S模式,利用remoting进行通信,在客户端启动的时候会多次获取代码表中的不同数据。)

1  public class CodeTableSingleTon 2 { 3     ///防止外部被实例化 4    private CodeTableSingleTon(){ 5        //进行数据的读取操作 6    } 7    //锁 8   private static readonly object _lock=new object(); 9 10   private static CodeTableSingleTon _instance;11   12    public static CodeTableSingleTon Instance13   {14   get15    {16     if(_instance==null)17      {18          lock(_lock){19             if(_instance==null) 20             {21             _instance=new CodeTableSingleTon();   22             }23           }24     }25   return _instance;26    }27 }28 29 30 }

上面代码就是项目的实现方式,我了解过单例模式,单例模式是控制对象的创建,可以实现延迟加载,只有在对象被调用的时候才会真正的执行对象的实例化,可以在一定程度上减少内存的耗用(是在不使用该对象的情况下)。既然在整个系统中只有一个该对象, 因为项目是采用多线程处理客户端的请求,所以每个线程都可以获取到该对象进行数据的获取,系统运行也没发现 由于这个对象的创建或者其他问题。

 

  但是我深入的想了一下,如果我在单例对象中加入一个计数器,表示单例对象被调用的次数,那么这个对象内部的属性 可能会同时被多个线程进行更新。

1 public class SingleTon 2 { 3  4   private static SingleTon _instance; 5   private static readonly object _lock=new object(); 6   private SingleTon(){} //私有的构造函数 确保该实例不能在外部直接通过new实例化 7   public static long totalNum=0;//初始化计数器默认值为0 8   public static SingleTon Instance 9   {10   get  11   {12     if(_instance==null)13       {14        lock(_lock)15        {16           if(_instance==null)17           {18           _instance=new SingleTon();19           }20        }21       }22       totalNum=totalNum+1; //每次调用计数器都会加1          //Consle.WriteLine(totalNum);23       return _instance;24   }25   }26 }

 

我尝试开启了多个线程来执行这段代码,没有发现totalNum的值存在由于多个线程的调用出现重复数据输出的情况。那么我心里一直在纠结一个事,就是说假如两个线程都在同一时间获取到了这个单例对象,那么都会依次执行计数器加1,如果说两个线程执行到totalNum=totalNum+1 这句话的时候不是在同时的,那么不会出现问题。

如果这两个线程中了彩票了,同时执行了totalNum=totalNum+1,那么就会导致计数器少算了一次调用吗?我在测试,开启了100个线程,没有发现重复的值存在,难道我的理解是错误的吗?我记得在多线程下操作同一数据是会出现这个问题的?不知道这个对单例模式是否适用呢?纠结纠结,求准确的回复

 

如果单例的方式存在问题,那么采用静态字段也会出现这个问题,就无法统计计数器了。mygod  脑袋要炸了

 

转载地址:http://ptloo.baihongyu.com/

你可能感兴趣的文章
(八)企业部分之nginx+tomcat+memcached负载均衡集群搭建
查看>>
图片格式转换工具与方法
查看>>
MySQL/sqlserver查询in操作 查询结果按in集合顺序显示
查看>>
如何使用Android Studio把自己的Android library分享到jCenter和Maven Central
查看>>
优美的配色方案设计
查看>>
设计模式——原型模式
查看>>
CSS——基础选择器
查看>>
App性能优化之内存优化
查看>>
Linux 灾难恢复 Linux 系统启动故障修复
查看>>
修复./mysql/proc
查看>>
快速地创建快顶尖的医学图像处理控件ImageGear Medical
查看>>
JSP注释方法
查看>>
Silverlight实用窍门系列:63.Silverlight中的Command,自定义简单Command
查看>>
LVS
查看>>
从软件交付看软件验收管理
查看>>
centos7 mysql数据库安装和配置
查看>>
Redis数据类型:字符串
查看>>
六种方式实现生产者消费者(未完)
查看>>
instanceof 的运用
查看>>
Linux 系统如何调整时区和时间
查看>>