java同步:Java单例对象同步问题探讨

        单例对象(Singleton)是种常用设计模式在Java应用中单例对象能保证在个JVM中该对象只有个例子存在正是由于这个特点单例对象通常作为存放配置信息载体它能保证其他对象读到信息例如在某个服务器该服务器配置信息可能存放在数据库或文件中这些配置数据由某个单例对象统读取服务进程中其他对象如果要获取这些配置信息只需访问该单例对象即可这种方式极大地简化了在复杂环境下尤其是多线程环境下配置管理但是随着应用场景区别也可能带来些同步问题   问题描述

  在多线程环境下单例对象同步问题主要体现在两个方面单例对象化和单例对象属性更新

  本文描述思路方法有如下假设:

  单例对象属性(或成员变量)获取是通过单例对象化实现也就是说在单例对象化时会从文件或数据库中读取最新配置信息

  其他对象不能直接改变单例对象属性单例对象属性变化来源于配置文件或配置数据库数据变化

  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>
Tags:  java对象 java面向对象 java面向对象编程 java同步

延伸阅读

最新评论

发表评论