单例模式:
单例模式(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的最佳方法。