Hello World

单例模式

一.核心作用

 
        保证一个类只有一个实例,并且提供一个访问该实例的全局访问点
 
        整个程序只需要一个实例的场景。比如任务管理器,回收站,连接池,线程池。
 

二.优点

 
        --由于单例模式只生成一个实例,减少系统性能的开销.当一个对象产生需要较多的资源时,可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存来解决.
        --单例模式可以在系统设置全局的访问点,优化资源访问.
 

三.常见实现方式

 
        主要:
                饿汉式    (线程安全    调用效率高       不能延时加载)
                汉式    (线程安全    调用效率不高    能延时加载)
 
        其他:
                双重检测锁式    将懒汉式的同步方法改为同步块
                静态内部类式    (线程安全    调用效率高        能延时加载)
                枚举单例           (线程安全    调用效率高        不能延时加载      可以防止反射和反序列化漏洞)
 

四.如何选用

 
                占用资源少,不需要延时加载
                枚举式   好于    饿汉式
 
                占用资源多,需要延时加载时
                静态内部类      好于    懒汉式
 

五.防止反射漏洞

 
                在构造方法中加一个判断,若对象不等于null,则抛出异常 
 

六.防止反序列化漏洞

 
                在该类中添加readResolve(){    return Instance;    }
 
package com.skd.designMode.simple;
/*
* 全局获取的实例是唯一的
* 1.构造方法私有化
* 2.对外提供静态方法(getInstance)来创建对象
*/
public class Person
{
    private static Person person;

    // 私有化构造方法
     

    private Person()
  {
    // 防止反射调用
    if (null != person)
    {
      throw new Exception();
    }
  }

    // 懒汉式
    // 延迟加载,方法需要同步,调用效率低
    public static synchronized Person getInstance()
    {
        if (person == null)
        {
            person = new Person();
        }
        return person;
    }         

    // 双重检测锁式
   // 此处将 person 声明为 volatile 即可得到唯一正确的 person 对象 public static Person getInstance2() { // 而且此处可能获得一个创建不完整的对象并返回
// 初始化一个对象的时候,会经历内存分配、初始化、返回对象在堆上的引用等一系列操作,这种方式产生的对象是一个完整的对象,可以正常使用。虚拟机可能会进行指令重排序 if (null == person) { synchronized (Person.class) { // 此处不判断可能创建多个对象,因为第一次判空未加锁 if (null == person) { person = new Person(); } } } return person; } // 防止反序列化 public static Person readResolve() {   return person; } } // 饿汉式 class People { // 类初始化时立即加载该对象,虚拟机的同步机制保证其线程安全! // 无法延时加载 private static People people = new People(); // 私有化构造方法 private People() { } // 方法不需要同步,调用效率高 public static People getInstance() { return people; } } // 静态内部类式 // 这种方式线程安全,调用效率高,延时加载 class Teacher { // 私有化构造方法 private Teacher(){} // 静态内部类 private static class Inner { // 类初始化时立即加载该对象,虚拟机的同步机制保证其线程安全! static final Teacher teacher = new Teacher(); } // 返回静态内部类的静态属性teacher public static Teacher getInstance() { return Inner.teacher; } } // 枚举式 package com.skd.simple; public enum Simple { // 枚举本身也是一种单例 // 线程安全,效率高,无法延时加载 INSTANCE(new Object()); Object obj; HAHA(Object object) { obj = object; } }

 

 

 
 
 
 
 
 
 
posted @ 2018-08-08 21:09  小小忧愁米粒大  阅读(161)  评论(0编辑  收藏  举报
瞅啥瞅,好好看书