单例模式要解决的问题?
保证一个类只有一个实例,并且可以全局访问它。
保证不能实例化多个该对象,必须自行创建该实例
单例类特点
构造方法私有,确保其他类无法通过new 关键字创建它,保证了该类只能有一个实例
有一个静态私有成员变量和静态公有工厂方法,工厂方法负责检查该实例
是否存在,并实例化,然后存储在静态成员变量中
什么时候使用单例模式?
1.要求产生唯一序列号
2.必须存在一个对象,客户端能够从一个公共资源访问到它
3.需要控制实例数目,创建一个对象消耗过多资源,如数据库连接,
为了节省系统资源的时候。
懒汉式加载
public class Singleton_lazy {
private static Singleton_lazy lazy = null;
private Singleton_lazy(){
}
public static synchronized Singleton_lazy getLazy(){
if(lazy == null){
lazy = new Singleton_lazy();
}
return lazy;
}
}
懒汉式加载-双重检查加锁
public class Singleton_lazy {
private volatile static Singleton_lazy lazy = null;
private Singleton_lazy(){
}
public static Singleton_lazy getLazy(){
if(lazy == null){
synchronized(this){
lazy = new Singleton_lazy();
}
}
return lazy;
}
}
使用到了volatile关键字来保证数据的可见性
饿汉式加载
public class Singleton_hunger {
private static Singleton_hunger lazy = new Singleton_hunger();
private Singleton_hunger(){
}
public static Singleton_hunger getLazy(){
return lazy;
}
}
案例
public class XmlConfigReader {
private static XmlConfigReader instance = null;
private JdbcConfig jdbcConfig = new JdbcConfig();
private XmlConfigReader(){
SAXReader reader = new SAXReader();
InputStream in =Thread.currentThread().getContextClassLoader().getResourceAsStream("sys-conf.xml");
try{
Document doc = reader.read(in);
Element driverNameElt = (Element)doc.selectObject("/config/db-info/driver-name");
Element urlElt = (Element)doc.selectObject("/config/db-info/url");
Element userNameElt = (Element)doc.selectObject("/config/db-info/user-name");
Element passwordElt = (Element)doc.selectObject("/config/db-info/password");
jdbcConfig.setDriverName(driverNameElt.getStringValue());
jdbcConfig.setUserName(userNameElt.getStringValue());
jdbcConfig.setPassword(passwordElt.getStringValue());
jdbcConfig.setUrl(urlElt.getStringValue());
}catch(DocumentException e){
e.printStackTrace();
}
}
public static synchronized XmlConfigReader getInstance(){
if(instance == null){
instance = new XmlConfigReader();
}
return instance;
}
public JdbcConfig getJdbcConfig(){
return jdbcConfig;
}
public static void main(String[] args) {
JdbcConfig jdbcConfig = XmlConfigReader.getInstance().getJdbcConfig();
}
}