一、单例设计模式是指java中某一个类只有一个实例,并且自行实例化对外提供服务。
1、如何保证对象的唯一性?
①、不允许其它程序使用new方式创建新的实例。
②、在该类中创建一个唯一的对象实例。
③、提供方法,共外界调用该实例。
2、步骤:
①、通过new方式私有化该类的一个对象实例。
②、私有化构造方法,其他程序无法创建实例。
③、提供公有的get方法,共外界调用该实例。
二、单例设计模式的几种设计方式
1、饿汉式
> class TestSingle{
private static TestSingle single=new TestSingle();
private TestSingle() {}
public static TestSingle getInstance() {
return single;
}
}
2、懒汉式(延迟加载模式)
> class TestSingle{
private static TestSingle single=null;
private TestSingle() {}
//这里必须是静态的,因为构造函数私有的,无法创建实例对象,只能通过类名调用。
public static TestSingle getInstance() {
if(single==null) {
single=new TestSingle();
}
return single;
}
}
三、多线程下的单例
1、饿汉式在类创建好的时候,就已经初始化好了一个对象实例,且提供方法对外访问,以后不会再改变,天生就是安全的。
2、懒汉式存在线程安全问题,有可能创建多个实例,违反单例唯一的情况,因此要解决线程安全问题。
①、双重检查锁定
> class Single1 implements Runnable{
private static Single1 single1=null;
public static Single1 getIntance() {
//第一个if判断句解决了线程效率问题
if(single1==null) {
synchronized(Single1.class) {
//第二个if语句解决了线程不安全问题
if(single1==null)
single1=new Single1();
}
}
return single1;
}
public void run() {
System.out.println(getIntance());
}
}
②、同步函数(在getIntance方法上加上同步)
> public synchronized static Single1 getIntance() {
if(single1==null)
single1=new Single1();
return single1;
}
③、静态内部类
>class TestSingle{
private static class Single {
private static TestSingle single=new TestSingle();
}
private TestSingle(){}
public static TestSingle getIntance(){
return Single.single;
}
}
四、饿汉式与懒汉式的区别
1、饿汉式是线程安全的,懒汉式线程不安全。
2、饿汉式不管系统用不用到该实例,都会在程序加载时先创建一个实例,占用内存资源,但在以后调用过程中会比较快。
懒汉式在需要用到时才会创建实例,第一次调用会比较慢,之后就和懒汉式想同了。
3、编程中常使用饿汉式。
五、在懒汉式的线程安全解决上
①、双重检查锁定使用了两次if判断语句,很好的解决了线程安全问题,同时避免了同步带来的效率问题。
②、使用同步函数,对效率影响比较大,因为每次使用都要同步,而我们大部分情况是不需要同步的。
③、使用内部类是线程安全的,同时没有性能损耗。