java中的单例模式

来源:互联网 发布:mac常用快捷键一览 编辑:程序博客网 时间:2024/06/10 02:48
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
  单例模式有一下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。


单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。




饿汉式单例类
 饿汉式单例类.在类初始化时,已经自行实例化 
 public class Singleton1 {
//私有的默认构造子
        private Singleton1() {}
       //已经自行实例化 
       private static final Singleton1 single = new Singleton1();
      //静态工厂方法 
      public static Singleton1 getInstance() {
          return single;
     }
}


懒汉式单例类
懒汉式单例类.在第一次调用的时候实例化 
  public class Singleton2 {
      //私有的默认构造子
      private Singleton2() {}
     //注意,这里没有final    
     private static Singleton2 single=null;
     //静态工厂方法 
      public synchronized  static Singleton2 getInstance() {
          if (single == null) {  
             single = new Singleton2();
         }  
        return single;
     }
 }




3.登记式单例类
  import java.util.HashMap;
  import java.util.Map;
  //登记式单例类.
  //类似Spring里面的方法,将类名注册,下次从里面直接获取。
 public class Singleton3 {
     private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
      static{
          Singleton3 single = new Singleton3();
          map.put(single.getClass().getName(), single);
     }
     //保护的默认构造子
     protected Singleton3(){}
     //静态工厂方法,返还此类惟一的实例
     public static Singleton3 getInstance(String name) {
         if(name == null) {
             name = Singleton3.class.getName();
             System.out.println("name == null"+"--->name="+name);
         }
         if(map.get(name) == null) {
             try {
                 map.put(name, (Singleton3) Class.forName(name).newInstance());
             } catch (InstantiationException e) {
                 e.printStackTrace();
             } catch (IllegalAccessException e) {
                 e.printStackTrace();
             } catch (ClassNotFoundException e) {
                 e.printStackTrace();
             }
         }
         return map.get(name);
     }
     //一个示意性的商业方法
     public String about() {    
         return "Hello, I am RegSingleton.";    
     }    
     public static void main(String[] args) {
         Singleton3 single3 = Singleton3.getInstance(null);
         System.out.println(single3.about());
     }
}




////////////////////////////////////////////////////////////////java中用反射来破坏单例


以饿汉式为例:


public static void main(String[] args) {
getInstance1();
}


public static void getInstance1()
{

try {
Class c = Class.forName("MySingleton");  //通过类名,得到Class
//Method[] m = c.getMethods();

//:此方法只能拿到public的属性:Field [] f = c.getFields();


MySingleton m1 = (MySingleton)c.newInstance();//只要名字为"MySingleton"的类存在,则此句话执行成功,因为可以调用构造方法,虽然它是私有的。

Field[] f = c.getDeclaredFields(); //可以拿到所有的属性
for(Field f1 : f)
{
System.out.println(f1.getName());
}

Field ff = c.getDeclaredField("single");
ff.setAccessible(true);//设置为此属性可以被改变值
ff.set(ff, new MySingleton());//如果不加final,则此句话不会报错,从而导致并不是一个单例。


//当然,用MySingleton m2 = (MySingleton)c.newInstance();本身就可以产生第二个对象了

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
原创粉丝点击