首页 > 代码库 > 单例模式和线程安全

单例模式和线程安全

前几天给项目的省市区加了redis。结果上线没多久就发生了数据错乱的现象,需要读取山东省的市可能返回的市广东的。一开始不明白哪里有问题,因为测试组的同学有测试过,在测试过程种并没有发生这样的情况。由于使用了servicestack.redis ,在4.x的版本对redis做了各种限制(要收费了,所以免费版就不大好用了),所以将dll换成3.x的版本,让测试组的同学做了一次压力测试,发现确实存在错乱的情况,调用少的时候,基本没这种情况,大概压了几万条,数据就已经错乱的惨不忍睹。这个时候应该放弃是dll的原因了,毕竟其它项目用的好好的,只能寻求其它方面的原因。我看了很多遍代码,都没有看出问题,只是缓存省市区而已,数据量又不大,查询也是简单明了,根本就没有什么难的地方。最后只能找leader帮忙了。

leader不愧是leader,一看我的代码就找到了问题。redis服务写了一个类,但这个类我不是每次调用都去实例化一个,而是选择了单例模式,而redis的底层服务并不是线程安全的,所以访问量多,线程之间就开始混乱了,各种数据乱窜,可能查山西省的时候,查湖北的服务占用了这个线程,服务返回的时候就变成了湖北的所有市了。

这次得深切的记住这个教训了,程序一定要保证线程的安全,还有,为什么会使用了单例模式,模式使用错误。

备注:线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

单例模式: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。(类似静态类)

单例模式和线程安全