单例模式三个主要特点:
1、构造方法私有化;
2、实例化的变量引用私有化;
3、获取实例的方法共有。
package com.ctl.singleton;
/**
* 懒汉式单例
* 该模式的特点是类加载时没有生成单例,
* 只有当第一次调用 getlnstance 方法时才去创建这个单例
*
*
* 注意:如果编写的是多线程程序,
* 则不要删除上例代码中的关键字 volatile 和 synchronized,
* 否则将存在线程非安全的问题。
* 如果不删除这两个关键字就能保证线程安全,
* 但是每次访问时都要同步,
* 会影响性能,且消耗更多的资源,
* 这是懒汉式单例的缺点
*/
public class LazySingleton {
//保证 instance 在所有线程中同步
private static volatile LazySingleton instance=null;
private LazySingleton() { } //private 避免类在外部被实例化
public static synchronized LazySingleton getInstance(){
if (instance==null){
instance=new LazySingleton();
}
return instance;
}
}
package com.ctl.singleton;
/**
* 饿汉式单例
* 该模式的特点是类一旦加载就创建一个单例,
* 保证在调用 getInstance 方法之前单例已经存在了。
*
*
* 饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,
* 以后不再改变,所以是线程安全的,
* 可以直接用于多线程而不会出现问题。
*/
public class HungrySingleton {
private static final HungrySingleton instance=new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return instance;
}
}
package com.ctl.singleton;
/**
* 双检锁/双冲校验锁(推荐)
* 这种方式采用双锁机制,安全且多线程情况下保持高效。
*/
public class DoubleCheckSingleton {
private volatile static DoubleCheckSingleton instance;
private DoubleCheckSingleton() {
}
public static DoubleCheckSingleton getInstance(){
if (instance==null){
synchronized (DoubleCheckSingleton.class){
if (instance==null){
instance=new DoubleCheckSingleton();
}
}
}
return instance;
}
}
package com.ctl.singleton;
/**
* 静态内部类创建单例(懒加载)(推荐)
* 这种方式能达到双检索方式的功效,堆静态域使用延迟加载,实现简单。
* 这种方式只适用于静态域的情况,双检索方式可在势力域需要延迟初始化时才使用
*/
public class SingletonIn {
private static class SingletonInner{
private static final SingletonIn INSTANCE=new SingletonIn();
}
private SingletonIn() {
}
public static final SingletonIn getInstance(){
return SingletonInner.INSTANCE;
}
}
package com.ctl.singleton;
/**
* 枚举单例(推荐)
*/
public enum EnumSingleton {
INSTANCE;
public void doMethod(){
}
}