Java基础

单例模式(kotlin实现)

2020-03-12  本文已影响0人  Merbng

/**kotlin 实现饿汉式单例
 * Created by merbng on 2020/3/11.
 */
class SingletonDemo {
    //1. kotlin 实现 饿汉式单例
    object SingletonTest1 {

    }

    //2.     kotlin 实现懒汉式单例
    class SingletonTest private constructor() {
        companion object {
            private var instance: SingletonTest? = null
                get() {
                    if (field == null) {
                        return SingletonTest()
                    } else {
                        return field
                    }
                }

            fun get(): SingletonTest {
                return instance!!
            }
        }
    }

    // 3.    线程安全的 懒汉式
    class SingletonTest2 private constructor() {
        companion object {
            private var instance: SingletonTest2? = null
                get() {
                    if (field == null) {
                        return SingletonTest2()
                    } else {
                        return field
                    }
                }

            @Synchronized
            fun get(): SingletonTest2 {
                return instance!!
            }
        }
    }

    //    4. 双重校验锁 式
    class SingletonTest3 private constructor() {
        //lazy 是接受一个lambda并返回一个Lazy实例的函数,返回的实例可以作为延迟属性的委托:第一次调用get()会执行已传递lazy()的lambda表达式并记录结果,后续调用get()只是返回记录的结果
        val instance: SingletonTest3 by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            SingletonTest3()
        }
    }
}

//     5.静态内部类式
class SingletonTest4 private constructor() {
    companion object {
        val instance = SingletonHolder.holder
    }

    object SingletonHolder {
        val holder = SingletonTest4()
    }
}

Java 实现

public class SingletonDemo{
  private static SingletonDemo instance =new SingletonDemo();
private SingletonDemo(){};
public static SingletonDemo getInstance(){
  return instance;
}
}
class SingletonDemo {
    private SingletonDemo() {
    }

    private static SingletonDemo instance;

    public static SingletonDemo getInstance() {
        if (instance == null) {
            return new SingletonDemo();
        }
        return instance;
    }
}
class SingletonDemo {
    private SingletonDemo() {
    }

    private static SingletonDemo instance;

    public static synchronized SingletonDemo getInstance() {//使用同步锁
        if (instance == null) {
            return new SingletonDemo();
        }
        return instance;
    }
}
class SingletonDemo {
    private SingletonDemo() {
    }

    private static volatile SingletonDemo instance;

    public static SingletonDemo getInstance() {
        if (instance == null) {
            synchronized (SingletonDemo.class) {
                if (instance == null) {
                    return new SingletonDemo();
                }
            }
        }
        return instance;
    }
}
class SingletonDemo5 {
    private SingletonDemo5() {
    }

    private static class SingletonHolder {
        private static SingletonDemo5 holder = new SingletonDemo5();
    }

    public static SingletonDemo5 getInstance() {
        return SingletonHolder.holder;
    }

}

双重校验锁的两个if判断有什么意义?

  1. 为何在synchronized外面判断?
    为了提高性能,如果拿掉这次判断那么在执行的时候就会直接运行synchronized,所以会使每个getInstance()都会得到一个静态内部类,这样的话锁的获取以及释放的开销(包括上下文切换,内存同步等)都不可避免,降低了效率,所以在synchronized前面加一次判空,则会大大降低synchronized的执行次数
  2. 为何在synchronized内部还有执行一次判空?
    因为可能会有多个线程一起进入同步块外的if,如果在同步块内不进行二次校验就会产生多个实例

在双重校验的情况下,保存实例的唯一静态变量要用volatile修饰,否则由于线程安全原因,一个类仍然会生成多个实例。

volatile

禁止指令重排序,保证多线程环境下的系统安全
被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存的,从而确保多个线程能正确的处理该变量。

参考链接

上一篇 下一篇

猜你喜欢

热点阅读