单例模式(多线程不安全,序列化不安全,反射不安全实例)
2015-11-19 12:33
405 查看
<pre name="code" class="html">import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; public class SingletonTwo implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private int number; private final static SingletonTwo s=new SingletonTwo(); private SingletonTwo(){} private SingletonTwo(int number){ this.number=number; } public static SingletonTwo getInstace() { return s; } public void sayHello(){ System.out.println("hello"); } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } /*private Object readSolve() { return s; }*/ 此段代码保证反序列化的安全性 public static void main(String[] args) { // TODO 自动生成的方法存根 SingletonTwo s=SingletonTwo.getInstace();//原始类 s.sayHello(); s.setNumber(10); ObjectOutputStream out; //反序列化不安全 try { //序列化 out = new ObjectOutputStream(new FileOutputStream("E://Singleton.txt")); out.writeObject(s); System.out.println("序列化成功"); out.close(); //反序列化 ObjectInputStream in = new ObjectInputStream(new FileInputStream("E://Singleton.txt")); SingletonTwo dest=(SingletonTwo) in.readObject(); dest.setNumber(100); System.out.println(dest.getNumber()); System.out.println("原始类 和 反序列话类相等吗 "+s.equals(dest)); } catch (FileNotFoundException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } catch (IOException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } catch (ClassNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } MyThread m=new MyThread(s);//多线程不安全 new Thread(m).start(); MyThread m1=new MyThread(s); new Thread(m1).start(); System.out.println("我是单例类"+s.getNumber()); try {//私有的反射机制不安全 Constructor<SingletonTwo>[] c=(Constructor<SingletonTwo>[]) Class.forName("com.create.destroy.object.singleton.SingletonTwo").getDeclaredConstructors(); for(int i=0;i<c.length;i++) { Constructor<SingletonTwo> cs=c[i]; Type []types=cs.getGenericParameterTypes(); if(types!=null && types.length>0) { for(int j=0;j<types.length;j++) { System.out.println(types[j]); } }else { SingletonTwo st=cs.newInstance(null); st.setNumber(1); System.out.println("原始类 和 反射类相等吗 "+st.equals(s)); } } } catch (SecurityException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (InstantiationException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IllegalAccessException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (InvocationTargetException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } class MyThread implements Runnable{ private SingletonTwo s; /* (非 Javadoc) * @see java.lang.Runnable#run() */ public MyThread(SingletonTwo s) { this.s=s; } @Override public void run() { // TODO 自动生成的方法存根 SingletonTwo t=SingletonTwo.getInstace(); System.out.println("********************************************************"); System.out.println("1.多线程类和原始类相等吗?"+s.equals(t)); System.out.println("如果再多线程中使用反序列化还会相等吗??? 使用反射机制呢??"); System.out.println("*************************可能为false****************************** "); } }总结如下:通过反射机制,一定不安全。多线程可能造成不安全,序列化也可能造成不安全
相关文章推荐
- php设计模式之单例模式实例分析
- JavaScript编程的单例设计模讲解
- C#设计模式之单例模式实例讲解
- JS模式之单例模式基本用法
- 深入理解JavaScript系列(25):设计模式之单例模式详解
- Java单例模式、饥饿模式代码实例
- Android源码学习之单例模式应用及优点介绍
- C++设计模式之单例模式
- C#窗口实现单例模式的方法
- Java线程安全中的单例模式
- PHP单例模式详细介绍
- PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
- php实现singleton()单例模式实例
- PHP中数据库单例模式的实现代码分享
- php利用单例模式实现日志处理类库
- 浅析php单例模式
- php单例模式实现方法分析
- javascript单例模式的简单实现方法
- js单例模式的两种方案
- php单例模式示例分享