在多线程环境下单例对象同步问题主要体现在两个方面单例对象化和单例对象属性更新
本文描述思路方法有如下假设:
单例对象属性(或成员变量)获取是通过单例对象化实现也就是说在单例对象化时会从文件或数据库中读取最新配置信息
其他对象不能直接改变单例对象属性单例对象属性变化来源于配置文件或配置数据库数据变化
1.1 单例对象化
首先讨论下单例对象化同步单例模式通常处理方式是在对象中有个静态成员变量其类型就是单例类型本身;如果该变量为null则创建该单例类型对象并将该变量指向这个对象;如果该变量不为null则直接使用该变量
其过程如下面代码所示:
1 public GlobalConfig {
2 private GlobalConfig instance = null;
3 private Vector properties = null;
4 private GlobalConfig {
5 //Load configuration information from DB or file
6 //Set values for properties
7 }
8 public GlobalConfig getInstance {
9 (instance null) {
10 instance = GlobalConfig;
11 }
12 instance;
13 }
14 public Vector getProperties {
15 properties;
16 }
17 }
18
这种处理方式在单线程模式下可以很好运行;但是在多线程模式下可能产生问题如果第个线程发现成员变量为null准备创建对象;这是第 2个线程同时也发现成员变量为null也会创建新对象这就会造成在个JVM中有多个单例类型例子如果这个单例类型成员变量在运行过程中变化会造成多个单例类型例子不致产生些很奇怪现象例如某服务进程通过检查单例对象某个属性来停止多个线程服务如果存在多个单例对象例子就会造成部分线程服务停止部分线程服务不能停止情况
1.2 单例对象属性更新
通常为了实现配置信息实时更新会有个线程不停检测配置文件或配置数据库内容旦发现变化就更新到单例对象属性中在更新这些信息时候很可能还会有其他线程正在读取这些信息造成意想不到后果还是以通过单例对象属性停止线程服务为例如果更新属性时读写区别步可能访问该属性时这个属性正好为空(null)就会抛出异常
="xspace-totlerecord">2="xspace-totlepages">1/2="xspace-current">12>
最新评论