单例设计模式
2016-01-04 21:55
274 查看
单例设计模式代码:
/** * 饿汉式 * @author zhangjianbin * */ public class Demo1 { //类初始化时,立即加载对象(如果后面没有调用这个类,而加载这个对象又比较耗时, //则白干了,并且是天然的线程安全的) private static final Demo1 s = new Demo1(); private Demo1() { } //不需要同步,所以调用效率高 public static Demo1 instance() { return s; } }
/** * 懒汉式 * @author zhangjianbin * */ public class Demo1 { private static Demo1 s = null; private Demo1() { } public static synchronized Demo1 instance() { if(s == null){ s = new Demo1(); } return s; } }
/** * 静态内部类实现单例 * * @author zhangjianbin * */ public class Demo3 { private Demo3() { } private static class InnerClass { private static final Demo3 sc = new Demo3(); } public static Demo3 getInstance() { return InnerClass.sc; } }
/** * 枚举实现单例 * * @author zhangjianbin * */ public enum Demo4 { instance;//本身就是一种单例的,线程安全的 }
单例设计模式反射和对象序列化破解:
//反射破解单例 public static void main(String[] args) throws Exception { // 获取类 Class<Demo1> forName = (Class<Demo1>) Class.forName("com.zhang.singleton.Demo1"); // 获取类的构造器 Constructor<Demo1> declaredConstructor = forName.getDeclaredConstructor(null); // 暴力破解,访问私有属性 declaredConstructor.setAccessible(true); // 利用构造器创建对象 Object newInstance = declaredConstructor.newInstance(null); Object newObject2 = declaredConstructor.newInstance(null); System.err.println(newInstance == newObject2); //false }
public static void main(String[] args) throws Exception { Demo1 d1 = Demo1.instance(); Demo1 d2 = Demo1.instance(); //对象序列化 FileOutputStream fos = new FileOutputStream(new File("d:/a.txt")); ObjectOutputStream os = new ObjectOutputStream(fos); os.writeObject(d1); os.close(); fos.close(); //对象反序列化 FileInputStream fs = new FileInputStream(new File("d:/a.txt")); ObjectInputStream in = new ObjectInputStream(fs); Object readObject = in.readObject(); System.err.println(d1 == readObject); //false } //阻止反序列化破解(在对象类中添加即可) private Object readResolve(){ return s; }
//多线程测试单例模式不同实现的执行效率 public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); int threadNum = 10; final CountDownLatch count = new CountDownLatch(threadNum); //有10个线程 for (int i = 0; i < threadNum; i++) { new Thread(new Runnable() { @Override public void run() { for (int i = 0; i <10000; i++) { Demo3 d = Demo3.getInstance(); } count.countDown();//每个线程执行完毕后,计数器减1 } }).start(); } count.await();//等待全部线程执行完毕后,才向下执行 long end = System.currentTimeMillis(); System.err.println(end- start); }
相关文章推荐
- 头文件中的using namespace
- 大话设计模式六原则专场二
- TCP/IP详解学习笔记
- 使用https的原因
- fundamentals of the jQuery library
- 简历
- BZOJ4388 : JOI2012 invitation
- Tomcat安装与配置
- 176,xib和storyboard的区别与相同点
- SQL--空值处理
- ubuntu 64位安装wps(亲测可用)
- java读取/写入属性文件
- 最大子序列之和
- Flux架构学习
- 5-12 两个数的简单计算器
- Java 泛型具体解释
- 【数组】Subsets
- 邮件系统服务器搭建记录(一)(Postfix+Cyrus-sasl+Courier-authlib+Dovecot+ExtMail+MySQL)
- _stdcal _cdecl
- 用代码判断大小端