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

原创 2015年11月19日 12:33:31
<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****************************** ");
	}
	
}
总结如下:通过反射机制,一定不安全。多线程可能造成不安全,序列化也可能造成不安全



                    

多线程锁和反射的再次理解

只有对象才有锁,一个对象有且只有一把锁。   只能使用对象的锁去同步,且只能同步方法/代码块,而不能同步变量和类;   同步损害并发性,应尽可能缩小同步范围。   分类  1代码块锁,2方法锁 同步整...

SpringMVC之组合注解@GetMapping

Spring4.3中引进了{@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping},来帮助简化常用的HTTP方法的映射,并...

解决多线程单例模式的线程不安全问题

DCL双检查锁机制public class MyConfig { private volatile static MyConfig myConfig = null;//volatile 保证每...

单例设计模式详解一:不安全的懒汉式(多线程环境验证)

单例设计模式详解一:不安全的懒汉式(多线程环境验证)单例设计模式详解一不安全的懒汉式多线程环境验证 写在前面的话 饿汉式 懒汉式 验证在多线程环境下懒汉式单例写法的不安全之处 写在前面的话前言:虽然工...

iOS多线程到底不安全在哪里?

链接:http://mrpeak.cn/blog/ios-thread-safety/ 不错的一篇文章,平时都知道atomic不能保证线程安全,但这边解释了一下作用以及原因,记录一下。 ...

多线程 list没有锁好导致的 不安全宕机问题

问题:因为代码中执行m_LoggerList.size()语句没有加锁,导致内存中出现了空指针,以下为状态推送线程的堆栈信息: (gdb) thread 20 [Switching to thread...

libcurl多线程超时设置不安全

这几天用libcurl总是莫名其妙地崩溃,今天终于发现问题所在了,转载一下~ (1), 超时(timeout) libcurl 是 一个很不错的库,支持http,ftp等很多的协议。使...

多线程环境下不安全的消息队列存取---线程不同步会造成隐患

前面, 我们把消息队列存取都放在主线程中, 而在实际应用中, 很多时候, 存消息队列在主线程, 取消息队列在其他线程(如网络线程)。 下面, 我们将之前的程序改为多线程程序: #include #i...
  • stpeace
  • stpeace
  • 2014年12月06日 00:17
  • 2211

libcurl多线程超时设置不安全

(1), 超时(timeout) libcurl 是 一个很不错的库,支持http,ftp等很多的协议。使用库最大的心得就是,不仔细看文档,仅仅看着例子就写程序,是一件危险的事情。我的程序崩溃了,我...

刨根问底Java多线程系列:线程不安全的最根本的原因是什么

一、引言 在多线程环境中,线程安全毫无疑问是最主要面对的问题。 找到线程不安全的根源,就好像找到了一把万能钥匙,解开程序中的任何线程不安全隐患。 12 二、分析 对于线程安全的定义...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:单例模式(多线程不安全,序列化不安全,反射不安全实例)
举报原因:
原因补充:

(最多只允许输入30个字)