JAVA-单例模式

单例模式

JAVA类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

特点

 - 单例模式类,只能有一个实例
 - 单例类必须自己创建自己的唯一实例
 - 单例类必须给所有其他对象提供这一实例

优点

 - 确保所有对象都访问一个实例,确保了访问唯一性 
 - 具有伸缩性,类自己控制实例化进程,类就在改变实例化进程上有响应的伸缩性
 - 节约资源,在系统内存中只存在一个对象,可以节约系统资源,避免重复资源消耗等问题

缺点

 - 对于不同用例场景变化的对象,可能会引起数据错误,不能保存彼此的状态
 - 没有抽象层,扩展难度大
 - 职责过重,违反“单一指责原则”
 - 可能造成连接池溢出,或者内存对象丢失

饿汉单例模式(预先加载法)

public class test1 {
    private test1() {
    }
    public int value;
    public static test1 instance = new test1();

    public test1 getInstance() {
        return instance;
    }

    public void setInt(int i){
        value=i;
    }
    public Integer getInt(){
        return value;
    }
}

class domian{
    public static void main(String[] args) {
        test1 t1=test1.instance.getInstance();
        t1.setInt(10);
        System.out.println(t1.getInt());
        
        test1 t2=test1.instance.getInstance();
        System.out.println(t2.getInt());
    }
}


/** 结果
10
10
**/

优点:

  • 1.线程安全
  • 2.在类加载的同事已经创建好一个静态对象,调用反应快

缺点:

  • 资源效率低,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化

懒汉单例模式


class test1 {

    public static test1 instance = null;
    public Integer value;

    private test1() {
    }

    public static test1 getInstance() {
        if (instance == null) {
            //多个线程判断instance都为null时,在执行new操作时多线程会出现重复情况
            instance = new test1();
        }
        return instance;
    }

    public void setInt(int i) {
        value = i;
    }

    public int getInt() {
        return value;
    }
}

class domain {
    public static void main(String[] args) {
        test1 t1 = test1.getInstance();
        t1.setInt(10);
        System.out.println(t1.getInt());

        test1 t2 = test1.getInstance();
        System.out.println(t2.getInt());
    }
}

/** 结果
10
10
**/

优点:

  • 1.资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。

缺点:

  • 线程不安全,没有加synchronized,多线程容易创建多个实例

双验锁/双重校验锁(DCL,double-checked locking双重检查锁定)

public class test1 {
    //volatile让变量每次在使用的时候,都从主存中取。而不是从各个线程的“工作内存”。
    private volatile static test1 singleton;
    public Integer value;
    private test1 (){}
    public static test1 getSingleton() {
        if (singleton == null) {
            //synchronized 同步锁
            synchronized (test1.class) {
                if (singleton == null) {
                    singleton = new test1();
                }
            }
        }
        return singleton;
    }

    public void serInt(int i){
        value=i;
    }
    public int getInt(){
        return value;
    }
}

class domain{
    public static void main(String[] args) {
        test1 t1=test1.getSingleton();
        t1.serInt(10);
        System.out.println(t1.getInt());

        test1 t2=test1.getSingleton();
        System.out.println(t2.getInt());

        t2.serInt(20);
        System.out.println(t1.getInt());
    }
}

/** 结果
10
10
20
**/

优点:

  • 1.线程安全,

缺点:

  • 双验锁机制,每次都要进行lock,造成额外的性能开销。

登记式-静态内部类

public class test1 {
    public Integer value;

    private static class SingletonHolder {
        private static final test1 INSTANCE = new test1();
    }

    private test1() {
    }

    public static final test1 getSingleton() {
        return SingletonHolder.INSTANCE;
    }

    public void serInt(int i) {
        value = i;
    }

    public int getInt() {
        return value;
    }
}


class domain {
    public static void main(String[] args) {
        test1 t1 = test1.getSingleton();
        t1.serInt(10);
        System.out.println(t1.getInt());

        test1 t2 = test1.getSingleton();
        System.out.println(t2.getInt());

        t2.serInt(20);
        System.out.println(t1.getInt());
    }
}

/** 结果
10
10
20
**/

优点:

  • 1.线程安全,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值