设计模式-单例模式
文章目录
- 单例模式
- 饿汉式单例
- 懒汉式单例
- 懒汉式加锁单例
- 双重锁校验单例
- 静态内部类单例
- 枚举单例
单例模式
单例模式主要是确保一个类在任何情况下都只有一个实例,并提供一个全局访问的点。
主要有以下几种
饿汉式单例
/*** 饿汉式* 类加载到内存后,就实例化了一个单例,JVM保证线程安全* 简单实用,推荐使用此方式* 缺点:无论是否用到,都会在类加载的时候就完成实例化*/
public class Singleton01 {private static final Singleton01 instance = new Singleton01();private Singleton01(){}public static Singleton01 getInstance(){return instance;}public static void main(String[] args) {Singleton01 instance1 = Singleton01.getInstance();Singleton01 instance2 = Singleton01.getInstance();System.out.println(instance1 == instance2);}
}
懒汉式单例
/*** 懒汉式单例* 什么时候用,什么时候初始化实例* 虽然也可以返回单例,但是会有线程安全问题*/
public class Singleton02 {private static Singleton02 instance;private Singleton02(){}public static Singleton02 getInstance(){if (instance == null){instance = new Singleton02();}return instance;}
}
懒汉式加锁单例
/*** 懒汉式加锁单例* 这里解决了线程安全的问题,但是性能也下降了*/
public class Singleton03 {private static Singleton03 instance;private Singleton03(){}public synchronized static Singleton03 getInstance(){if (instance == null){try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}instance = new Singleton03();}return instance;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(Singleton03.getInstance().hashCode());}).start();}}
}
双重锁校验单例
/*** 双重锁校验* 这样可以缩小锁锁定的代码块,并且也保证了线程安全*/
public class Singleton04 {private static volatile Singleton04 instance;private Singleton04(){}public static Singleton04 getInstance(){if (instance == null){synchronized (Singleton04.class){if (instance == null){instance = new Singleton04();}}}return instance;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(Singleton04.getInstance().hashCode());}).start();}}
}
静态内部类单例
/*** 静态内部类方式* JVM保证了单例* 加载外部类时不会加载内部类,这样也实现了懒加载*/
public class Singleton05 {private Singleton05(){}private static class SingletonHolder{private static final Singleton05 instance = new Singleton05();}public static Singleton05 getInstance(){return SingletonHolder.instance;}public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(Singleton05.getInstance().hashCode());}).start();}}
}
枚举单例
/*** 枚举实现单例* 枚举本身就是单例的* 解决了线程安全问题,也防止反序列化*/
public enum Singleton06 {INSTANCE;public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread(() -> {System.out.println(Singleton06.INSTANCE.hashCode());}).start();}}
}