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

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));
 }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值