6、单子模式(单例模式)

一、功能:保证在整个应用中只有一个实例存在。(例如只创建一个窗口,JDBC连接数据库程序只连接一个等)。

二、概念:对某个类只能存在一个对象实例,并且该类提供了一个取得其对象实例的方法。

三、单子模式第一种写法:

  步骤:1、首先私有化构造器,这样在外部就不能随意new对象了

     2、在类的内部定义并产生那个唯一的对象,并限制其访问权限为private

     3、提供给外部一个public类型的静态方法,可以获得该唯一对象。

    

/**
 * Created by Administrator on 2018/3/1 0001.
 * 最典型的单例模式、单子模式
 */
public class A {
    private A(){}//第一步:私有化构造器,这样主类就不能随意的实例化多个对象了
    private static A a=null;//第二步:初步定义对象,方便后面方法中调用判断该变量
    public static A Getinstance(){//这里必须是静态方法,因为当没有对象时,无法在主类中调用该方法。
        if(a==null){  //第三步:如果没有a对象,就实例化,有的话就返回当前的对象
            a=new A();

        }
        return a;

    }
}

   

/**
 * Created by Administrator on 2018/3/1 0001.
 */
public class TestA {
    public static void main(String[] args) {
        A a1=A.Getinstance();
        A a2=A.Getinstance();
        System.out.println(a1==a2);
    }
}

 缺点:在多线程中不能正常工作

四、单子模式第二种写法

    这种写法能够在多线程中很好的工作:不需要同步。

/**
 * Created by Administrator on 2018/3/1 0001.
 * 多线程时保证单个线程调用的单例模式、单子模式,效率低下
 */
public class B {
    private B(){}
    private static B b=null;
    public synchronized static B Getinstance(){
        if(b==null){
            b=new B();
        }
        return b;
    }
}
/**
 * Created by Administrator on 2018/3/1 0001.
 */
public class TestB {
    public static void main(String[] args) {
        B b1=B.Getinstance();
        B b2=B.Getinstance();
        System.out.println(b1==b2);
    }
}

缺点:效率低下

  

五、单子模式的第三种写法 

  使用classloader的反射机制来保证初始化instance时只有一个线程。

  使用内部类

/**
 * Created by Administrator on 2018/3/1 0001.
 * 使用classloader来保证初始化instance时只有一个线程,先加载C类,当需要时再调用Getinstance方法,加载C1类,初始化
 */
public class C {
     public static class C1{
        private static final C1 c=new C1();//final的定义就是不可再被更改
    }
    public static C1 Getinstance(){
         return C1.c;
    }

}
/**
 * Created by Administrator on 2018/3/1 0001.
 */
public class TestC {
    public static void main(String[] args) {
        C.C1 c1=C.Getinstance();
        C.C1 c2=C.Getinstance();
        System.out.println(c1);
        System.out.println(c2);
    }

}

六、单子模式第四种写法

  用volatile来锁定变量,用synchronize锁定方法的双重锁定单子模式

public class D {
    private D(){}
    private volatile static D d=null;//在jvm的底层对变量进行单线程操作
    public synchronized static D Getinstance(){//synchronized锁定方法
        if(d==null){
            d=new D();
        }
        return d;
    }
}
public class TestD {
    public static void main(String[] args) {
        D d1=D.Getinstance();
        D d2=D.Getinstance();
        System.out.println(d1==d2);
    }
}
原文地址:https://www.cnblogs.com/television/p/8511870.html