Java单例模式的写法
2016-04-01 16:14
411 查看
1、常规写法
这种方法可以实现延时加载,但是有一个致命弱点:线程不安全。如果有两条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。
2、添加线程安全
对创建单例模式的资源设置同步锁,注意关键字volaitile是必需的,volatile禁止指令重排序优化。多线程代码由于编译器优化,在实际执行的时候可能与我们编写的顺序不同。编译器只保证程序执行结果与源代码相同,却不保证实际指令的顺序与源代码相同。这在单线程看起来没什么问题,然而一旦引入多线程,这种乱序就可能导致严重问题。volatile关键字就可以从语义上解决这个问题。
volatile在JDK1.5引入
3、静态内部类的写法
本质还是一样的,由于静态内部类只会被加载一次,所以这种写法也是线程安全的。
网上还有枚举类的写法,大家可以搜索一下。
public class Singleton { private static Singleton singleton = null; private Singleton(){} public static Singleton getSingleton() { if(singleton == null) singleton = new Singleton(); return singleton; } }
这种方法可以实现延时加载,但是有一个致命弱点:线程不安全。如果有两条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。
2、添加线程安全
public class Singleton { private static volatile Singleton singleton = null; private Singleton(){} public static Singleton getSingleton(){ synchronized (Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } return singleton; } }
对创建单例模式的资源设置同步锁,注意关键字volaitile是必需的,volatile禁止指令重排序优化。多线程代码由于编译器优化,在实际执行的时候可能与我们编写的顺序不同。编译器只保证程序执行结果与源代码相同,却不保证实际指令的顺序与源代码相同。这在单线程看起来没什么问题,然而一旦引入多线程,这种乱序就可能导致严重问题。volatile关键字就可以从语义上解决这个问题。
volatile在JDK1.5引入
3、静态内部类的写法
public class Singleton { private static class Holder { private static Singleton singleton = new Singleton(); } private Singleton(){} public static Singleton getSingleton(){ return Holder.singleton; } }
本质还是一样的,由于静态内部类只会被加载一次,所以这种写法也是线程安全的。
网上还有枚举类的写法,大家可以搜索一下。
相关文章推荐
- action中调用Spring 注解 service 总是为空
- myeclipse内存不足问题
- myeclipse内存不足问题
- java多线程-需要知道的几个概念(待续..)
- windows环境下获取安卓应用的MD5签名,SHA1签名,SHA256签名等(适用于Android studio和eclipse)
- 模拟Spring解析xml文件,以及实现IOC (DI)的示例
- Java —— 报错
- Spring整合Struts2
- java高级之线程范围内的共享数据
- Java并发编程:深入剖析ThreadLocal
- java多线程的同步和死锁
- Java —— Hibernate4 No Session found for current thread
- java设计模式之创建型模式-工厂方法模式
- Spring中的用到的设计模式大全
- spring中用到哪些设计模式
- Java单链表基本操作(七)--排序
- java 给指定时间加上天数or给当前日期加天数
- Java中数据的简单转换
- Java中比较器 Comparator 的简单例子
- Java中比较器 Comparator 的简单例子