懒汉式实现单例模式读取配置文件
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//懒汉式
public class Singleton1 {
/**
* 定义一个类变量用来存放创建好的类实例
*/
private static Singleton1 uniqueInstance = null;
/**
* 用来存放配置文件的参数paramA的值
*/
private String paramA;
/**
* 用来存放配置文件的参数paramB的值
*/
private String paramB;
//返回参数paramA的值
public String getParamA() {
return paramA;
}
//返回参数paramB的值
public String getParamB() {
return paramB;
}
/**
* 私有化构造方法
*/
private Singleton1(){
readConfig();
}
/**
* 读取配置文件,把读取的信息设置到属性上
*/
private void readConfig() {
Properties p = new Properties();
InputStream in = Singleton1.class.getResourceAsStream("AppConfig.properties");
try {
p.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.paramA = p.getProperty("paramA");
this.paramB = p.getProperty("paramB");
}
/**
* 定义一个方法来为客户端提供Singleton1类实例
* @return 一个Singleton1类实例
*/
public static Singleton1 getSingleton1Instance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton1();
return uniqueInstance;
}
return uniqueInstance;
}
}
饿汉式实现单例模式读取配置文件
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//饿汉式
public class Singleton2 {
/**
* 定义一个类变量用来存放创建好的类实例
*/
private static Singleton2 uniqueInstance = new Singleton2();
/**
* 用来存放配置文件的参数paramA的值
*/
private String paramA;
/**
* 用来存放配置文件的参数paramB的值
*/
private String paramB;
//返回参数paramA的值
public String getParamA() {
return paramA;
}
//返回参数paramB的值
public String getParamB() {
return paramB;
}
/**
* 私有化构造方法
*/
private Singleton2(){
readConfig();
}
/**
* 定义一个方法来为客户端提供Singleton2类实例
* @return 一个Singleton2类实例
*/
public static Singleton2 getSingleton2Instance(){
return uniqueInstance;
}
/**
* 读取配置文件,把读取的信息设置到属性上
*/
private void readConfig() {
Properties p = new Properties();
InputStream in = Singleton1.class.getResourceAsStream("AppConfig.properties");
try {
p.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.paramA = p.getProperty("paramA");
this.paramB = p.getProperty("paramB");
}
}
缓存实现单例模式
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
//用缓存来实现单例模式
public class Singleton3 {
/**
* 定义一个默认的key值
*/
private final static String DEFAULT_KEY ="one";
/**
* 缓存实例的容器
*/
private static Map<String,Object> map = new HashMap<String,Object>();
/**
* 用来存放配置文件的参数paramA的值
*/
private String paramA;
/**
* 用来存放配置文件的参数paramB的值
*/
private String paramB;
//返回参数paramA的值
public String getParamA() {
return paramA;
}
//返回参数paramB的值
public String getParamB() {
return paramB;
}
/**
* 构造方法私有化
*/
private Singleton3(){
readConfig();
}
/**
* 定义一个方法来为客户端提供Singleton3类实例
* @return 一个Singleton3类实例
*/
public static Singleton3 getSingleton3Instance(){
Singleton3 instance = (Singleton3) map.get("one");
if(instance==null){
instance = new Singleton3();
map.put(DEFAULT_KEY, instance);
}
return instance;
}
/**
* 读取配置文件,把读取的信息设置到属性上
*/
private void readConfig() {
Properties p = new Properties();
InputStream in = Singleton1.class.getResourceAsStream("AppConfig.properties");
try {
p.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.paramA = p.getProperty("paramA");
this.paramB = p.getProperty("paramB");
}
}
通过双重检查加锁的方式实现单例模式
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//通过双重检查加锁的方式实现单例模式
public class Singleton4 {
/**
* 用来存放配置文件的参数paramA的值
*/
private String paramA;
/**
* 用来存放配置文件的参数paramB的值
*/
private String paramB;
//返回参数paramA的值
public String getParamA() {
return paramA;
}
//返回参数paramB的值
public String getParamB() {
return paramB;
}
/**
* 构造方法私有化
*/
private Singleton4(){
readConfig();
}
/**
* 保存实例变量添加volatile关键词修饰
*/
private volatile static Singleton4 uniqueInstance = null;
/**
* 读取配置文件,把读取的信息设置到属性上
*/
private void readConfig() {
Properties p = new Properties();
InputStream in = Singleton4.class.getResourceAsStream("AppConfig.properties");
try {
p.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.paramA = p.getProperty("paramA");
this.paramB = p.getProperty("paramB");
}
/**
* 定义一个方法来为客户端提供Singleton4类实例
* @return 一个Singleton4类实例
*/
public static Singleton4 getSingleton4Instance(){
//先检查实例是否存在,如果不存在才进入下面的同步快
if(uniqueInstance == null){
//同步块,线程安全的创建实例对象
synchronized (Singleton4.class){
uniqueInstance = new Singleton4();
return uniqueInstance;
}
}
return uniqueInstance;
}
}
通过JVM保证线程安全的方式实现单例模式(高人的方法)
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//通过JVM保证线程安全性
public class Singleton5 {
private String paramA;
private String paramB;
public String getParamA() {
return paramA;
}
public String getParamB() {
return paramB;
}
private static class SingletonHolder{
private static Singleton5 instance = new Singleton5();
}
public static Singleton5 getSingleton5Instance(){
return SingletonHolder.instance;
}
private Singleton5(){
readConfig();
}
private void readConfig() {
Properties p = new Properties();
InputStream in = Singleton1.class.getResourceAsStream("AppConfig.properties");
try {
p.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.paramA = p.getProperty("paramA");
this.paramB = p.getProperty("paramB");
}
}
下面是本文所使用的配置文件:
AppConfig.properties
内容为:
paramA = AAAAAA
paramB = BBBBBB
五种方法的比较
第一种方法,是以时间换空间,实现了延迟加载,但线程不安全;
第二种方法,是以空间换时间,没有实现延迟加载,线程安全;
第三种方法,与第一种方法相比,由于是通过缓存,所以效率大大提高,但同样是线程不安全的;
第四种方法,实现了延迟加载和线程安全,使用双重检查加锁的方法,使得性能不会有太大的影响,但会屏蔽掉虚拟机中一些必要的代码优化,所以运行效率并不是很高;
第五种方法:高人的方法,这个解决方案被称为Lazy initialization holder class模式,这个模式综合使用了java的类级内部类和多线程缺省同步锁的知识,很巧妙的同时实现了延迟加载和线程安全。