单例模式:指的就是任何时候一个类中只有一个实例被调用,就是一个类只保证只有一个对象。废话太多真的不好。直接开路。
懒汉模式:
节省空间,消耗时间。
package SingletonStudy;
/**
* 懒汉模式就是在需要创建对象的时候才创建,所以初始化的时候是空,
* 当调用该类中的统一的获取对象的方法是才初始化对象并返回。
* @author vm510
*
*/
public class LanHan {
private static LanHan lanHan;//初始化为空
private LanHan() {//把本类设置为私有,不可直接访问。
super();
}
/*
* 有一个线程锁,调用该方法时获得对象并返回,因为是需要初始化,所以访问时间长一点,但是节省了空间。
*/
public synchronized static LanHan getObject() {
if (lanHan == null){
lanHan = new LanHan();
}
return lanHan;
}
}
这样的类是不能直接new一个对象出来用的,实际测试一下:
饿汉模式:
节省时间,浪费空间。
package SingletonStudy;
/**
* 饿汉模式,先初始化对象,在判断对象调用
* @author vm510
*/
public class EHan {
private static EHan eHan = new EHan();//一开始就初始化好了对象等着调用
private EHan(){//私有化对象,不能直接初始化调用。
super();
}
/*
* 一般情况下因为已经有了对象,所以调用时非常的快,但是空间上有一定的消耗。
*/
public synchronized static EHan getObject(){
if (eHan == null){
eHan = new EHan();
}
return eHan;
}
}
双重判断加锁机制:
因为上面的synchronized东西每次都要进行同步实例判断以保证实例的唯一性,可能会有时间上的浪费,所以我们在前面先来判断。
package SingletonStudy;
/**
* 双重判断加锁机制
* @author vm510
*/
public class DoubleLock {
/*
* volatile表示被其所修饰的变量的值不会被本地线程缓存,就是用完一个对象就会销毁,没有缓存之说
*/
private static volatile DoubleLock doubleLock = null;//采用懒汉模式初始化对象
private DoubleLock(){
super();
}
public DoubleLock getObject(){
if (doubleLock == null){//判断一
synchronized (DoubleLock.class) {//线程判断二
doubleLock = new DoubleLock();
}
}
return doubleLock;
}
}
类部类实现:
极力推荐使用的,毕竟线程锁这些东西不靠谱。用类部类既可以不提前初始化实例,又可以不进行线程锁的判断。就比较正常了。
package SingletonStudy;
/*
* 这里的话,初始化外部类的时候类部类是不会初始化的,要用的时候才会初始化,这样一说是不是瞬间明白了好多。
*/
public class ClassInClass {
public static class InClass{//类部类
private static ClassInClass classInClass = new ClassInClass();
}
private ClassInClass(){
super();
}
public static ClassInClass getObject(){//调用对象的方法
ClassInClass classInClass1 = InClass.classInClass;
return classInClass1;
}
}
总结:自己动手,天下我有。
长风破浪会有时,直挂云帆济沧海。共勉。