单例模式是设计模式中使用最普遍的模式之一。
单例模式能带来以下两点好处:
1.对于频繁使用的对象,可以省略创建对象所花的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。
2.由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将GC压力,缩短GC停顿时间。
废话不多说,直接贴代码,三种创建方式,以及各自的优缺点
/**
* @author pengl
* 2014-5-1
* 描述:单例模式创建方式一 预创建模式
* 预创建模式的缺点:JVM加载单例类时,单例对象会被创建,不管有没用到。
* 单例模式的好处:a.节省创建对象时间 b.系统内存使用频率降低,减轻GC压力,缩短GC停顿时间
*/
public class SingletonPreLoading {
private SingletonPreLoading(){
System.out.println("SingletonPreLoading is created");
}
private static SingletonPreLoading singleton = new SingletonPreLoading();
public static SingletonPreLoading getInstance(){
return singleton;
}
public static void sleep(){
System.out.println("sleeping...");
}
}
/**
* @author pengl
* 2014-5-1
* 描述:单例模式创建方式二 懒加载模式
* 懒加载模式的缺点:多线程下,由于有同步锁,降低了效率
* 单例模式的好处:a.节省创建对象时间 b.系统内存使用频率降低,减轻GC压力,缩短GC停顿时间
*/
public class SingletonLayLoading {
private SingletonLayLoading(){
System.out.println("SingletonLayLoading is created");
}
private static SingletonLayLoading singleton = null;
/**
* 为避免多线程导致重复创建对象 加上同步锁
* @return
*/
public static synchronized SingletonLayLoading getInstance(){
if(singleton==null){
singleton = new SingletonLayLoading();
}
return singleton;
}
public static void sleep(){
System.out.println("sleeping...");
}
}
/**
* @author pengl
* 2014-5-1
* 描述:单例模式创建方式三 兼备懒加载和效率
* 优点1:当SingletonBothLoading类加载时,其内部类并不会被初始化,故可延迟加载
* 优点2:getInstance()方法被调用时才会加载内部类,实例的建立是在类加载完成时,故天生对多线程友好,不需要使用同步关键字
* 单例模式的好处:a.节省创建对象时间 b.系统内存使用频率降低,减轻GC压力,缩短GC停顿时间
*/
public class SingletonBothLoading {
private SingletonBothLoading(){
System.out.println("SingletonBothLoading is created");
}
private static class SingletonHolder{
private static SingletonBothLoading instance = new SingletonBothLoading();
}
public static SingletonBothLoading getInstance(){
return SingletonHolder.instance;
}
public static void sleep(){
System.out.println("sleeping...");
}
}
/**
*
* @author pengl
* 2014-5-1
* 描述:
*/
public class SingletonTest {
@Test
public void testpre(){
SingletonPreLoading.sleep();
}
@Test
public void testlay(){
SingletonLayLoading.sleep();
}
@Test
public void testboth(){
SingletonBothLoading.sleep();
}
}