应用
资源管理器
属性管理器
多例是为了存储数据的,单例是为了共享可以减少资源消耗
饿汉式–JVM保证线程安全(简单推荐)
因为JVM可以保证每个类只加载一次,所以设置为static就可以保证对象只会被new一次,static是在加载链接初始化中的初始化就会赋值的,只执行一次。
多线程都没关系
但是用到与否,类加载就已经实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.deltaqin.designPattern.d01_singleton;
public class Single01 {
private static final Single01 INSTANCE = new Single01();
public static Single01 getInstance() { return INSTANCE; }
public void m() { System.out.println("hi"); }
public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(()->{ System.out.println(getInstance().hashCode()); }).start(); } } }
|
懒汉式–自己保证线程安全
锁加在方法:效率变低
方法内部的代码块:只加在需要的时候,
需要双重验证,否则多个线程进入第一个 if 的时候,其他线程先执行获得锁初始化,自己就重复初始化了。
volatile防止重排序,获得空的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package com.deltaqin.designPattern.d01_singleton;
public class Single02 {
private static volatile Single02 instance;
public static Single02 getInstance1() { if (instance == null) {
try{ Thread.sleep(1000); }catch (Exception e) { e.printStackTrace(); }
synchronized (Single02.class ) { if (instance == null) { instance = new Single02(); } } } return instance; }
public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(()-> { System.out.println(Single02.getInstance1().hashCode()); }).start(); } } }
|
(最好)静态内部类–懒加载+JVM保证只有一个实例
加载外部类时不会加载内部类
静态内部类以及静态属性保证了只有一个实例产生
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.deltaqin.designPattern.d01_singleton;
public class Single03 {
private static class Single { public static final Single03 instance = new Single03(); }
public static Single03 getInstance() { return Single.instance; }
public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(()-> { System.out.println(Single03.getInstance().hashCode()); }).start(); } } }
|
enum 枚举单例
优点:实现简单,枚举本身就是单例模式。由JVM从根本上提供保障!避免通过反射和反序列化的漏洞!
缺点:无延迟加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.deltaqin.designPattern.d01_singleton;
public enum Single04 { INSTANCE;
public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(()-> { System.out.println(Single04.INSTANCE.hashCode()); }).start(); } } }
|