一、懒汉式实现单例模式读取配置文件
- 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的类级内部类和多线程缺省同步锁的知识,很巧妙的同时实现了延迟加载和线程安全。