java单例模式例子

1.懒汉模式,基础。线程不安全。

package example;

/**
 * 
 * @author Administrator
 *懒汉模式,只有在调用getInstance的时候才会加载。
 */
public class Singleton {

    private static Singleton instance;
    
    private Singleton() {
        //私有方法,不能通过new关键字实例化对象。
    }
    //static关键字,保证对象属于类级别。
    public static Singleton getInstance() {
        
        if(null == instance) {//如果instance不存在就实例化,只能在单线程下保证单例。
            instance = new Singleton();
        }
        return instance;
    }
}

2.懒汉模式,线程安全的,在获取实例化对象的方法 上加锁。

package example;

public class SingletonSafeNotEfficient {
    
    private static SingletonSafeNotEfficient instance;
    
    //私有方法,保证不能通过new关键字实例化对象。
    private SingletonSafeNotEfficient() {
        
    }
    
    /**
     * 暴露实例化对象的方法。static保证类级别的方法,静态方法,通过类.获取对象。
     * 在类方法上加锁,效率低下。并且大部分情况下不需要加锁。
     * 加锁,保证多线程的安全。
     * @return 返回实力对象
     */
    public synchronized static SingletonSafeNotEfficient getInstance() {
        
        if(null == instance) {
            instance = new SingletonSafeNotEfficient();
        }
        return instance;
    }
    
}

3,单例,多线程安全,提高效率,双重锁检查机制。

package example;

/**
 * 单例模式,懒汉模式,保证线程安全的情况下,提高效率。
 * 在JDK1.5之后,双重检查锁定才能够正常达到单例效果。
 * @author Administrator
 *
 */
public class SingletonSafeAndEfficient {

    private static SingletonSafeAndEfficient instance;
    
    private SingletonSafeAndEfficient() {
        
    }
    //俗称双重检查锁定
    public static SingletonSafeAndEfficient getInstance() {
        
        if(null == instance) {
            
            synchronized (SingletonSafeAndEfficient.class) {
                
                if(null == instance) {
                    instance = new SingletonSafeAndEfficient();
                }
                
            }
        }
        return instance;
    }
}

4,单例,饿汉模式,类加载的时候立即加载。线程安全。有时候可能没有用到实力对象,浪费内存。

package example;

/**
 * 饿汉模式是在类加载的时候实例化,所以就不存在多线程安全(不考虑反射)
 * @author Administrator
 *
 */
public class SingletonHungry {
    
    //类加载就实例化对象。
    private static SingletonHungry instance= new SingletonHungry();
    
    //私有空构造方法,保证不能new对象。
    private SingletonHungry() {
        
    }
    
    public static SingletonHungry getInstance() {
        
        return instance;
    }
    
    
}

5,同样的饿汉模式,和上一个是同样的原理。

package example;

/**
 * 同样是饿汉模式,使用静态代码块
 * @author Administrator
 *
 */
public class SingletonHungryBlock {
    
    private static SingletonHungryBlock instance = null;
    
    static {
        instance = new SingletonHungryBlock();
    }
    
    //替换默认的public构造方法
    private SingletonHungryBlock() {
        
    }
    
    public static SingletonHungryBlock getInstance() {
        return instance;
    }
}

6.单例,对上面的改进。

package example;

public class SingletonClassLoader {
    
    private static class ClassHolder{
        
        private static final SingletonClassLoader INSTANCE= new SingletonClassLoader();
        
    }
    
    private SingletonClassLoader() {
        
    }
    //因为SingletonHolder类没有被主动使用,
    //只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化INSTANCE
    public static final SingletonClassLoader getInstance() {
        
        return ClassHolder.INSTANCE;
    }
}

7.枚举,java1.5以后推荐的写法:

package example;

/*
 * 关于枚举
 * 参考:http://www.cnblogs.com/liaokailin/p/3196253.html
 */
public enum EnumSingleton {
    
        INSTANCE;
        private Resource instance;
        EnumSingleton() {
            instance = new Resource();
        }
        public Resource getInstance() {
            return instance;
        }
    }
class Resource{
    
}
/**
 * 上面的类Resource是我们要应用单例模式的资源,具体可以表现为网络连接,数据库连接,线程池等等。 
获取资源的方式很简单,只要 SomeThing.INSTANCE.getInstance() 即可获得所要实例。下面我们来看看单例是如何被保证的: 
首先,在枚举中我们明确了构造方法限制为私有,在我们访问枚举实例时会执行构造方法,同时每个枚举实例都是static final类型的,也就表明只能被实例化一次。在调用构造方法时,我们的单例被实例化。 
也就是说,因为enum中的实例被保证只会被实例化一次,所以我们的INSTANCE也被保证实例化一次。 
 */

 

posted @ 2017-12-10 15:52  美金  阅读(269)  评论(0)    收藏  举报