您的位置:首页 > 其它

单例模式(多线程不安全,序列化不安全,反射不安全实例)

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

}
总结如下:通过反射机制,一定不安全。多线程可能造成不安全,序列化也可能造成不安全

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单例模式