- /**
- 恶汉单例模式, 用空间换时间的思想进行对象的初始化, 在多线程的情况下, 故不存在线程安全问题.
- @author Administrator
- */
- public class WickedManSingleTon {
- private static WickedManSingleTon instance=new WickedManSingleTon();
- private WickedManSingleTon() {
- }
- public static WickedManSingleTon getIntance() {
- return instance;
- }
- }
懒汉模式:
- /**
- 懒汉单例模式, 用时间换空间的概念, 实例化单例对象, 在多线程的情况下, 存在线程安全的问题.
- @author Administrator
- */
- public class LasyManSingleTon {
- private static LasyManSingleTon instance=null;
- private LasyManSingleTon() {
- }
- public static LasyManSingleTon getInstance() {
- if(instance==null) {
- instance=new LasyManSingleTon();
- }
- return instance;
- }
- }
- /**
- 双检索实现单例模式
- @author Administrator DCL 模式的优点就是, 只有在对象需要被使用时才创建, 第一次判断 INSTANCE ==
- null 为了避免非必要加锁, 当第一次加载时才对实例进行加锁再实例化. 这样既可以节约内存空间, 又可以保证线程安全. 但是, 由于 jvm 存在乱序执行功能, DCL 也会出现线程不安全的情况. 具体分析如下:
- INSTANCE = new DCLInstance();
- 这个步骤, 其实在 jvm 里面的执行分为三步: ??
- 1. 在堆内存开辟内存空间. ?
- 2. 在堆内存中实例化 SingleTon 里面的各个参数. ?
- 3. 把对象指向堆内存空间.
- 由于 jvm 存在乱序执行功能, 所以可能在 2 还没执行时就先执行了 3, 如果此时再被切换到线程 B 上, 由于执行了 3,INSTANCE
- 已经非空了, 会被直接拿出来用, 这样的话, 就会出现异常. 这个就是著名的 DCL 失效问题.
- */
- public class DCLInstance {
- // 手写双检索
- private static DCLInstance instance = null;// 优化采用 volatile
- private DCLInstance() {
- }
- public static DCLInstance getInstance() {
- if (instance == null) {
- // 同步操作
- synchronized (DCLInstance.class) {
- if (instance == null) {
- // 多线程环境下可能会出现问题的地方
- instance = new DCLInstance();
- }
- }
- }
- return instance;
- }
- }
- /**
- @author Administrator
- 内部类的形式实现单例模式:
- 静态内部类的优点是: 外部类加载时并不需要立即加载内部类, 内部类不被加载则不去初始化 INSTANCE, 故而不占内存.
- 即当 SingleTon 第一次被加载时, 并不需要去加载 SingleTonHoler, 只有当 getInstance() 方法第一次被调用时,
- 才会去初始化 INSTANCE, 第一次调用 getInstance() 方法会导致虚拟机加载 SingleTonHoler 类,
- 这种方法不仅能确保线程安全, 也能保证单例的唯一性, 同时也延迟了单例的实例化.
- */
- public class InerClassMakeIntance {
- private static InerClassMakeIntance instance =null;
- private InerClassMakeIntance() {
- }
- public static InerClassMakeIntance getInstance() {
- return InerInstance.t1;
- }
- private static class InerInstance {
- private static InerClassMakeIntance t1 = new InerClassMakeIntance();
- }
- }
来源: http://www.bubuko.com/infodetail-3194135.html