您的位置:首页 > 编程语言 > Go语言

设计模式GOF23之单例模式效率测试与反射和反序列化问题的解决

2015-03-26 22:43 666 查看
package com.bjsxt.cn.singleton;
import java.io.ObjectStreamException;import java.io.Serializable;
/** * 2015年3月26日22:14:22 * 懒汉式单例模式 * 该懒汉式的特点是: *  1, 构造器私有 *  2, 私有静态属性,类型为该类的对象,但是在声明时并没有初始化。因为Lazy load。因为懒惰 *  3, 静态访问私有的那个静态属性的静态方法。但是在该方法体中先要检查该静态属性是否为空,为空则new,否则直接返回 * 测试如何防止反射和反序列化破坏单例模式的有效性 * @author wanna * */public class SingletonDemo6 implements Serializable{ private SingletonDemo6() {  if (instance != null) {   throw new RuntimeException();     } }  private static SingletonDemo6 instance;  //因为该方法加了同步synchronized,效率低,但是具有延时加载的能力。提高了资源的利用率 public static synchronized SingletonDemo6 getInstance() {  if (instance == null) {   instance = new SingletonDemo6();  }  return instance;   } //反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象! public Object readResolve() throws ObjectStreamException{  return instance; }  }
package com.bjsxt.cn.singleton;
import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.ObjectStreamException;import java.lang.reflect.Constructor;
public class client  { public static void main(String[] args)throws Exception {  SingletonDemo6 s1 = SingletonDemo6.getInstance();  SingletonDemo6 s2 = SingletonDemo6.getInstance();  System.out.println(s1);  System.out.println(s2);    //通过反射调用私有构造器。  //这种问题通过在SingletonDemo6私有构造器中判断,如果要new对象,就报异常  /*  Class<SingletonDemo6> clazz = (Class<SingletonDemo6>) Class.forName("com.bjsxt.cn.singleton.SingletonDemo6");  Constructor<SingletonDemo6> constructor = clazz.getDeclaredConstructor(null);  constructor.setAccessible(true);  SingletonDemo6 s3 = constructor.newInstance();  SingletonDemo6 s4 = constructor.newInstance();    System.out.println(s3);  System.out.println(s4);  */    //通过反序列化破坏单例  //为了防止反序列化破坏单例,可以在SingletonDemo6类中定义方法readResolve()  /*   * //反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象!   public Object readResolve() throws ObjectStreamException{    return instance;   }   *   * */  FileOutputStream fos = new FileOutputStream("D:/a.txt");  ObjectOutputStream oos = new ObjectOutputStream(fos);   oos.writeObject(s1);  oos.close();  fos.close();  ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/a.txt"));  SingletonDemo6 s5 = (SingletonDemo6) ois.readObject();  System.out.println(s5);     }}/*使用反射破坏单例模式运行结果 *  com.bjsxt.cn.singleton.SingletonDemo6@659e0bfd com.bjsxt.cn.singleton.SingletonDemo6@659e0bfd com.bjsxt.cn.singleton.SingletonDemo6@2a139a55 com.bjsxt.cn.singleton.SingletonDemo6@15db9742 * * 使用反序列化破坏单例模式结果 *  com.bjsxt.cn.singleton.SingletonDemo6@659e0bfd com.bjsxt.cn.singleton.SingletonDemo6@659e0bfd com.bjsxt.cn.singleton.SingletonDemo6@5c647e05 * * */
package com.bjsxt.cn.singleton;
import java.util.concurrent.CountDownLatch;/* * 2015年3月26日22:14:11 * 测试多线程模式下五种单例模式的执行效率 * CountDownLatch * A synchronization aid that allows one or more threads * to wait until a set of operations being performed in other threads completes. * * */public class client2 { public static void main(String[] args) throws Exception{  int threadNum = 10;  CountDownLatch count = new CountDownLatch(threadNum);  long start = System.currentTimeMillis();  for (int i=0; i<threadNum; i++) {   new Thread(new Runnable() {        @Override    public void run() {     for (int i=0; i<1000000; i++) {      Object o = SingletonDemo1.getInstance();     // Object o = SingletonDemo5.Instance;     }     count.countDown();    }   }).start();  }    count.await();  long end = System.currentTimeMillis();  System.out.println("总耗时 " + (end - start)); }}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: