延迟加载(lazy load)是(也称为懒加载)Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。
在这,Hibernate这个框架无需理会,可以看出,所谓延时加载技术,就是优化内存资源的利用效率,你要用什么,在用的时候再给你,而不是你迟点会用到的时候就马上给你。
一般情况下,单例模式是这样的:
public class Singleton{
private static Singleton instance=null;//Singleton类定义实例对象,其实类名与实例名都可以自己定义
private Singleton(){}//隐藏构造器,不能通过new来实例化。
private static Singleton getInstance(){
if(instance==null)
instance==new Singleton();
return instance;
}
}
单例模式最大的优点就是保证某个类只能被实例化一次,就像古代参拜皇帝一样,皇帝只有一个供大家参拜。
实例如下:
Singleton a=Singleton.getInstance();
Singleton b=Singleton.getInstance();
Singleton c=Singleton.getInstance();
其中a、b、c得到的对象都是instance这个对象,因此,实现了单例模式。
这样做其实也很危险,当a、b、c三个对象同时对类中的其他对象进行修改时就会产生线程不安全问题,要怎么解决呢?有三个办法,第一,在声明instance的同时直接实例化它,第二,要用到Java1.5引入的Lock进程锁第三,用synchronized块。
下面演示一下:
方法一:public class Singleton{
private static Singleton instance=new Singleton();//Singleton类定义实例对象,其实类名与实例名都可以自己定义
private Singleton(){}//隐藏构造器,不能通过new来实例化。
private static Singleton getInstance(){
return instance;
}
}
方法二:
public class Singleton{
private static Singleton instance=null;//Singleton类定义实例对象,其实类名与实例名都可以自己定义
private static Object lockObj=new Object();
private Singleton(){}//隐藏构造器,不能通过new来实例化。
private static Singleton getInstance(){
if(instance==null){
lock(lockObj){
if(instance==null) {
instance==new Singleton();
}
}
}
return instance;
}
}
方法三:
public class Singleton{
private static Singleton instance=null;//Singleton类定义实例对象,其实类名与实例名都可以自己定义
private Singleton(){}//隐藏构造器,不能通过new来实例化。
private static Singleton getInstance(){
if(instance==null){
synchronized(this){
instance==new Singleton();
}
}
return instance;
}
}
但是,这样做还有一个缺点,那就是每次声明的时候就已经实例化了该对象,最糟糕的情况是还实例化了却没有用到该对象,怎样才可以优化它呢?这个时候我们就要用到延时加载了,先看下例:
public class Singleton{
private static class SingletonLazyLoad {
static Singleton instance=new Singleton();//Singleton类定义实例对象,类名与实例名都可以自己定义
}
private Singleton(){}//隐藏构造器,不能通过new来实例化。
private static Singleton getInstance(){
return SingletonLazyLoad.instance;
}
}
这样,既保证了资源有效利用,又保证了其安全性。