单例模式

单例模式:
单例模式(Singleton):保证一个类只有一个实际,并提供一个访问它的全局访问点。

有时我们需要一个类在进程中只有一个实例对象,比如我们点击一个图标,打开一个程序,再次点击图标时,因为程序已经打开,就不再重复打开。这时候我们就需要只有一个程序对象被实例化。

通常我们可以让一个全局变量使得一个对象被访问,但他不能防止你实例化多个对象。一个最好的办法是,让类自行负责保存它的唯一实例对象。这个类可以保证没有其他实例被创建,并提供一个访问该实例的方法。

单例模式组成:
1、将采用单例模式的类的构造方法使用private修饰。

2、在类的内部定义该类的实例对象,并将其封装成private static类型。

3、定义一个静态方法返回定义的实例对象。

单例模式实例代码:

// 方法一:单例模式,恶汉模式
public class Singleton {
    // 类中自行管理实例对象
    private static Singleton instance = new Singleton();
    // private修饰的构造函数
    private Singleton() {
        // TODO Auto-generated constructor stub
    }

    public static Singleton GetInstance(){
        return instance;
    }
}

以上是饿汉模式,这种模式在类被加载时就会产生实例化对象。该模式有点是:简单,不存在线程安全问题。缺点是:在加载类是就创建对象,对象会一直占用内存一直到对象被销毁。

// 懒汉模式
public class Singleton {

    private static Singleton instance = null;
    public Singleton() {
        // TODO Auto-generated constructor stub
    }

    public static Singleton GetInstance(){
        if(instance == null){
        // 同步代码块,保证多线程安全
            synchronized (Singleton.class) {
                if(instance == null){
                    instance = new Singleton();
                }
            }   
        }
        return instance;
    }
}

以上代码的单例模式叫做懒汉模式,在调用获取对象方法才创建对象。效率高,线程安全,多线程操作原子性。

客户端代码:

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Singleton singleton = Singleton.GetInstance();
        Singleton singleton1 = Singleton.GetInstance();

        if(singleton.equals(singleton1)){
            System.out.println("=");
        }
    }

}

提醒:

享有特权的客户端可以借助AccessObject.setAccessible方法,通过反射机制调用到私有构造器。

Class clazz = Class.forName("Singleton");
Constructor cons = clazz.getConstructor(null);
cons.setAccessible(true);  
cons.newInstance(null);

如果需要抵御这种攻击,可以修改构造器,让它在被要求创建第二次实例的时候抛出异常。

从JDK1.5开始,提供了一种新的Singleton方法,只需要写一个包含单个元素的枚举类型:

// Singleton
public enum Singleton {
    INSTANDE;

    private Singleton() {
        // TODO Auto-generated constructor stub
        System.out.println("cons");
    }
}

client.java

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Singleton singleton = Singleton.INSTANDE;
        Singleton singleton1 = Singleton.INSTANDE;
    }

这种方法在功能上也前面一种方法相近,但是它更加简洁,无偿地提供了序列化机制,并且绝对防止多次实例化,即时在面对复杂的序列化或者反射攻击的时候。虽然这种方法还没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值