记录单例模式遇到多线程时的多种情况
来源:互联网 发布:python ssh 爆破 编辑:程序博客网 时间:2024/05/13 18:26
单例模式有很多种,也有很多人总结了,我这里自己总结多线程与单例模式的情况,这样感觉印象会比较深刻。简单的懒汉饿汉式单例我就不写了。。
(1)DCL双检查锁机制,用来实现多线程环境中的延迟加载单例设计模式。完整的实现代码如下:(运行结果自己可以复制粘贴就可以运行测试了)
package wu;public class MyObject {private static MyObject instance ;private MyObject (){}public static MyObject getInstance(){if(instance==null){synchronized(MyObject.class){if(instance==null){instance=new MyObject();}}}return instance;}public static void main(String [] args){MyThread_1 t1=new MyThread_1();MyThread_1 t2=new MyThread_1();t1.start();t2.start();}}class MyThread_1 extends Thread{public void run(){System.out.println(MyObject.getInstance().hashCode());}}
这种情况下可以防止多线程执行时的不安全性(即是利用了第二个instance判断做到)
(2),使用静态内部类实现单例模式,利用静态的东西只会被内存加载一次的特性,完整实现代码如下:
package wu;public class staticTest {private static class MyObject{private static MyObject instance=new MyObject();private MyObject(){}public MyObject getInstance(){return MyObject.instance;}}public static void main(String [] args){MyThread_2 t1=new MyThread_2();MyThread_2 t2=new MyThread_2();t1.start();t2.start();}}class MyThread_2 extends Thread{public void run(){System.out.println(MyObject.getInstance().hashCode());}}
注意:如果是遇到序列化对象的话,静态类这种实现方式还是采用默认的方式,最后还是多实例,而不是单例的!
(3),序列化方式的单例实现:完整代码如下:
package wu;import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamException; import java.io.Serializable; public class SerializeTest implements Serializable{ private static final long serialVersionUID = -1734754422962712867L;// 单例 (这里随便写一种单例模式就可以了.) private static SerializeTest instance ; public static SerializeTest getInstance(){ if(instance==null){ synchronized(SerializeTest.class){ if(instance==null){ instance=new SerializeTest(); } } }return instance; } private SerializeTest(){ } //防止单例对象在序列化后生成“多例” private Object readResolve() throws ObjectStreamException { return instance; } //序列化克隆 public SerializeTest deepCopy() throws Exception{ ByteArrayOutputStream os = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(SerializeTest.getInstance()); InputStream is = new ByteArrayInputStream(os.toByteArray()); ObjectInputStream ois = new ObjectInputStream(is); SerializeTest test = (SerializeTest) ois.readObject(); return test; } public static void main(String args[]) { // 只要打印出的TestSingleton对象地址一致, // 说明依然是单例对象 //把readResolve方法注释掉的话地址就不一致了! System.out.println(SerializeTest.getInstance().hashCode()); try { System.out.println(SerializeTest.getInstance().deepCopy().hashCode()); } catch (Exception e) { e.printStackTrace(); } } }
(4)使用static代码块来实现,代码如下:
package wu;public class staticTest {private static staticTest instance=null;private staticTest(){}static{ instance=new staticTest();}public static staticTest getInstance(){return instance;}public static void main(String [] args){MyThread_2 t1=new MyThread_2();MyThread_2 t2=new MyThread_2();t1.start();t2.start();}}class MyThread_2 extends Thread{public void run(){System.out.println(MyObject.getInstance().hashCode());}}
(5)还有一种enum类型也比较少见,具体代码我就不写了,不过我可以举个例子,也就是数据库连接代码那里可以使用enum方式实现的单例。
大概一些重要也有点偏的方法实现多线程单例模式。
0 0
- 记录单例模式遇到多线程时的多种情况
- 多线程情况下的单例模式创建
- 转:多线程情况下的单例模式
- 单例模式 各种情况下的演进 多线程
- 自己遇到的一个单例模式的问题记录
- 当单例模式遇到多线程并发的时候
- 单例模式:单线程和多线程并发情况下的对象创建
- 单例模式的多种实现方式
- 单例模式的多种实现
- 单例模式的多种写法
- 关于单例模式的多种写法
- Android多种单例模式的使用
- 单例模式的多种实现方式
- 3.单例模式的多种写法
- 单例模式的多种实现
- 【单例模式】的多种实现方式
- 设计模式1:单例模式(考虑多线程的情况)
- 单例模式的写法(考虑多线程的情况下)
- FileUtile(文件操作工具包)
- IE6右浮动问题
- ios面试题2
- 预处理命令
- 最大间距问题
- 记录单例模式遇到多线程时的多种情况
- VS2012中使用MFC制作简单的计算器
- mysql 编码设置utf8 windows下的命令行插入中文报错
- spring4.2整合hibernate5配置文件
- Java HttpClient 的入门例子
- 获取一定长度的随机字符串 RandomStringGenerator
- Linux学习笔记之论坛安装
- 简易爬虫实现校园网剩余流量查询
- 持续集成篇_09_复制maven项目