单例模式

//懒汉式单例类.在第一次调用的时候实例化自己   
public class Singleton {  
    private Singleton() {}  
    private static Singleton single=null;  
    //静态工厂方法   
    public static Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
    }  
} 


//饿汉式单例类.在类初始化时,已经自行实例化   
public class Singleton1 {  
    private Singleton1() {}  
    private static final Singleton1 single = new Singleton1();  
    //静态工厂方法   
    public static Singleton1 getInstance() {  
        return single;  
    }  
}  


两者区别:
1: 饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,

        懒汉式本身是非线程安全的,为了实现线程安全三种方法解决:

1:在getInstance方法上加同步

public static synchronized Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
}  
2: 双重检查锁定

public static Singleton getInstance() {  
        if (singleton == null) {    
            synchronized (Singleton.class) {    
               if (singleton == null) {    
                  singleton = new Singleton();   
               }    
            }    
        }    
        return singleton;   
    } 
3: 静态内部类

public class Singleton {    
    private static class LazyHolder {    
       private static final Singleton INSTANCE = new Singleton();    
    }    
    private Singleton (){}    
    public static final Singleton getInstance() {    
       return LazyHolder.INSTANCE;    
    }    
}    
2:资源加载和性能

饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成,

而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。

至于1、2、3这三种实现又有些区别,

第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的,

第2种,在getInstance中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗

第3种,利用了classloader的机制来保证初始化instance时只有一个线程,所以也是线程安全的,同时没有性能损耗,所以一般我倾向于使用这一种。

3:应用

懒汉式:

1:保证一个数据库对应一个sessionFactory 
   2:保证同一个客户端用户使用同一个session对象

public class HibernateSessionFactory {
	private static SessionFactory sessionFactory;

	// 使用本地线程对象管理session对象
	private final static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

	// 保证满足第一个条件
	static {
		buildSessionFactory();
	}

	/**
	 * 定义构建SessionFactory对象的方法 2017年4月14日
	 * 
	 * @return SessionFactory buildSessionFactory
	 */
	public static void buildSessionFactory() {
		// 判断SessionFactory是否为空
		if (sessionFactory == null) {
			Configuration cfg = new Configuration().configure();
			ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties())
					.build();
			sessionFactory = cfg.buildSessionFactory(serviceRegistry);
		}
	}

	/**
	 * 定义获取session的方法
	 * 2017年4月14日
	 * @return
	 * Session
	 * getSession
	 */
	public static Session getSession() {
		// 从本地线程中获取Session对象
		Session session = threadLocal.get();

		// 判断session为null需要把创建的session对象方法放到本地线程中
		if (session == null) {
			// 判断sessionFactory为空
			if(sessionFactory == null){
				buildSessionFactory();
			}
			
			session = sessionFactory.openSession();

			// 设置到本地线程中
			threadLocal.set(session);
		}
		return session;
	}
	
	public static void closeSession(){
		Session session = threadLocal.get();
		
		if(session.isConnected() && session!=null){
			session.close();
			session = null;
			threadLocal.set(null);
		}
	}
}


jdbc属性文件解析类

public class PropertiesParser extends Properties {
	
	private PropertiesParser() {
		
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static PropertiesParser pp;
	
	// 装载属性文件 
    {
		try {
			this.load(this.getClass().getClassLoader().getResourceAsStream("jdbc.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
    
    /**
     * 定义创建当前类实例的静态的方法
     */
    public static PropertiesParser newInstance() {
    	if (pp == null) {
    		pp = new PropertiesParser();
    	}
    	
    	return pp;
    }
    
    /**
     * 定义通过属性文件中对应key获取值得方法
     */
    public String getValueByKey(String key) {
    	return getProperty(key);
    }
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值