01单例模式

编程

单例模式写法常规的有7-8种吧,但是有部分写法是不太严谨的,在多线程当中,有可能会造成线程安全的问题,推荐三种比较完美的写法。

写法一

饿汉式(基于classloder机制避免了多线程的同步问题

/**

* 1、利用JVM保证一个类只加载一次来保证创建对象的唯一性。加载类时会进行静态变量初始化。

* 2、私有化构造方法

*/

public class Singleton01 {

private static final Singleton01 INSTANCE = new Singleton01();

private Singleton01(){}

public static Singleton01 getInstance(){

return INSTANCE;

}

public static void main(String[] args) {

for(int i = 0; i<100; i++) {

//测试在高并发时,返回的对象是否一致

new Thread(() -> System.out.println(INSTANCE.hashCode())).start();

}

}

}

写法二

利用静态内部类来实现更安全的机制(静态内部类需要用到时才会加载,对饿汉式有一些改进)

public class Singleton02 {

private static class Holder {

private static final Singleton02 INSTANCE = new Singleton02();

}

private Singleton02(){}

public static Singleton02 getInstance(){

return Holder.INSTANCE;

}

public static void main(String[] args) {

for(int i = 0; i<100; i++) {

//测试在高并发时,返回的对象是否一致

new Thread(() -> System.out.println(getInstance().hashCode())).start();

}

}

}

写法三

利用枚举类型,最简洁高效(避免反射、序列化问题)
避免反射:可能通过反射调用类的构造方法,进行创建对象。但反射在通过newInstance创建对象时,会检查该类是否ENUM修饰,如果是则抛出异常,反射失败。
序列化问题:任何一个readObject方法,不管是显式的还是默认的,它都会返回一个新建的实例,这个新建的实例不同于该类初始化时创建的实例。

public enum Singleton03 {

INSTANCE;

public String other() {

return "Hello World.";

}

public static void main(String[] args) {

for(int i = 0; i<100; i++) {

//测试在高并发时,返回的对象是否一致

new Thread(() -> System.out.println(INSTANCE.hashCode())).start();

}

}

}

 

以上是 01单例模式 的全部内容, 来源链接: utcz.com/z/518929.html

回到顶部