Maison  >  Article  >  Java  >  java 单例模式的简单实现

java 单例模式的简单实现

黄舟
黄舟original
2017-03-10 11:38:521081parcourir


定义:确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例
场景:确保某个类只有一个对象的场景,避免产生多个对象消耗过多资源。如,访问IO、DB等资源时,就要考虑使用单例模式
class Singleton1 {// 饿汉式 
	private static Singleton1 intance = new Singleton1();//直接初始化
	private Singleton1() {}
	public static Singleton1 getInstance() {
		return intance;
	}
}

class Singleton2 {// 懒汉式
	private static Singleton2 intance;
	private Singleton2() {}
	public static Singleton2 getInstance() {//用到的时候 才加载
		if (intance == null) {
			intance = new Singleton2();
		}return intance;
	}
}

class Singleton3 {// 懒汉式 线程安全
	private static Singleton3 intance;
	private Singleton3() {}
	public synchronized static Singleton3 getInstance() {//用到的时候 才加载, 加锁  多线程调用,都有一个加锁的动作
		if (intance == null) {
			intance = new Singleton3();
		}
		return intance;
	}
}

class Singleton4 {// 懒汉式 线程安全
	private static Singleton4 intance;
	private Singleton4() {}
	public static Singleton4 getInstance() {//用到的时候 才加载
		synchronized (Singleton4.class) {// 加锁 
			if (intance == null) {
				intance = new Singleton4();
			}    
		}
		return intance;
	}
}

public class Singleton {//双重检查 懒汉式 线程安全
	private static Singleton intance;
	private Singleton() {}
	
	public static Singleton getInstance() {
		
		if (intance == null) {//检查1:如果为null,再执行到下一步加锁;不为null不执行加锁操作
			synchronized (Singleton.class) {//类级锁
				if (intance == null) {//检查2:为null,才new一个实例
					intance = new Singleton();
				}
			}
		}
		return intance;
	}
}


静态内部类单例模式: 延迟加载,线程安全

public class StaticInnerClassSingleton implements Serializable {

    private StaticInnerClassSingleton() {

    }

    public static StaticInnerClassSingleton getInstance() {
        return Builder.instance;
    }

    private static class Builder {
        private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
    }

    private Object readResolve() throws ObjectStreamException {
        return Builder.instance;
    }
}

关于函数:readResolve(), 反序列化时的钩子函数,它是私有的,重写防止在反序列化时生成新的实例

以上所有单例方式都有这个问题,严格来说都需要重写

枚举:可以有属性和方法,一个元素的枚举即是单例模式,默认线程安全

public enum  SingletonEnum {
    INSTANCE_A;

    private SingletonEnum() {//构造方法只能是private的,不写也是
        id = idGenerate++;
    }

    public String aa;

    public String getAa() {
        return aa;
    }

    private int idGenerate = 1000;
    private final int id;

    public int getId() {
        return id;
    }
}


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn