> 文章列表 > 第四章 单例模式

第四章 单例模式

第四章 单例模式

文章目录

  • 前言
  • 一、单例模式的介绍
  • 二、单例模式的 8 种实现方式(懒汉式要注意线程安全问题)
    • 1、饿汉式(静态常量)
      • 优缺点:可能会造成内存的浪费,但也只能浪费内存
    • 2、饿汉式(静态代码块)
    • 3、懒汉式(线程不安全)不推荐
      • 缺点:多线程不安全
    • 4、懒汉式(线程安全,同步方法)添加 synchronized 关键字
      • 缺点效率太低
    • 5、懒汉式(同步代码块)不能使用,解决不了线程安全问题
    • 6、懒汉式(双重检查加 volatile关键字)推荐使用
    • 7、静态内部类
      • 优缺点
    • 8、使用枚举实现单例懒加载
  • 三、JDKの RunTime 类使用的是单例模式
  • 四、单例模式注意事项和细节说明

前言

第四章 单例模式
第四章 单例模式
第四章 单例模式


一、单例模式的介绍

第四章 单例模式

二、单例模式的 8 种实现方式(懒汉式要注意线程安全问题)

第四章 单例模式

1、饿汉式(静态常量)

第四章 单例模式

代码示例

package tanchishell.SJMS;public class SingletonTest01 {public static void main(String[] args) {
//测试Singleton instance = Singleton.getInstance();Singleton instance2 = Singleton.getInstance();System.out.println(instance == instance2); // trueSystem.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}
}//饿汉式(静态变量)
class Singleton {//1. 构造器私有化, 外部能 newprivate Singleton() {}//2.本类内部创建对象实例private final static Singleton instance = new Singleton();//3. 提供一个公有的静态方法,返回实例对象public static Singleton getInstance() {return instance;}
}输出
true
instance.hashCode=460141958
instance2.hashCode=460141958

优缺点:可能会造成内存的浪费,但也只能浪费内存

第四章 单例模式

2、饿汉式(静态代码块)

第四章 单例模式

代码示例


package tanchishell.SJMS;public class SingletonTest01 {public static void main(String[] args) {
//测试Singleton instance = Singleton.getInstance();Singleton instance2 = Singleton.getInstance();System.out.println(instance == instance2); // trueSystem.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}
}//饿汉式(静态变量)
class Singleton {//1. 构造器私有化, 外部能 newprivate Singleton() {}//2.本类内部创建对象实例
//    private final static  Singleton instance = new Singleton();private static Singleton instance;static {//使用静态代码块,不再使用 final 修饰为常量instance = new Singleton();}//3. 提供一个公有的静态方法,返回实例对象public static Singleton getInstance() {return instance;}
}输出true
instance.hashCode=460141958
instance2.hashCode=460141958

第四章 单例模式

3、懒汉式(线程不安全)不推荐

第四章 单例模式

代码示例

package tanchishell.SJMS;public class SingletonTest01 {public static void main(String[] args) {
//测试Singleton instance = Singleton.getInstance();Singleton instance2 = Singleton.getInstance();System.out.println(instance == instance2); // trueSystem.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}
}//饿汉式(静态变量)
class Singleton {//1. 构造器私有化, 外部能 newprivate Singleton() {}//2.本类内部创建对象实例private static Singleton instance;//3. 提供一个公有的静态方法,返回实例对象public static Singleton getInstance() {if(instance == null){instance = new Singleton();}return instance;}
}输出true
instance.hashCode=460141958
instance2.hashCode=460141958

缺点:多线程不安全

第四章 单例模式

4、懒汉式(线程安全,同步方法)添加 synchronized 关键字

第四章 单例模式

package tanchishell.SJMS;public class SingletonTest01 {public static void main(String[] args) {
//测试Singleton instance = Singleton.getInstance();Singleton instance2 = Singleton.getInstance();System.out.println(instance == instance2); // trueSystem.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}
}//饿汉式(静态变量)
class Singleton {//1. 构造器私有化, 外部能 newprivate Singleton() {}//2.本类内部创建对象实例private static Singleton instance;//3. 提供一个公有的静态方法,返回实例对象/ 添加  synchronized 关键字保证线程安全 */public static synchronized Singleton getInstance() {if(instance == null){instance = new Singleton();}return instance;}
}输出true
instance.hashCode=460141958
instance2.hashCode=460141958

缺点效率太低

第四章 单例模式

5、懒汉式(同步代码块)不能使用,解决不了线程安全问题

第四章 单例模式

第四章 单例模式

6、懒汉式(双重检查加 volatile关键字)推荐使用

第四章 单例模式
第四章 单例模式

package tanchishell.SJMS;public class SingletonTest01 {public static void main(String[] args) {
//测试Singleton instance = Singleton.getInstance();Singleton instance2 = Singleton.getInstance();System.out.println(instance == instance2); // trueSystem.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}
}//饿汉式(静态变量)
class Singleton {//1. 构造器私有化, 外部能 newprivate Singleton() {}//2.本类内部创建对象实例,添加 volatile 保证有序性和可见性private static volatile Singleton instance;//3. 提供一个公有的静态方法,返回实例对象/ 双重检查加 volatile 关键字 */public static Singleton getInstance() {if(instance == null){synchronized (Singleton.class){if(instance == null){instance = new Singleton();}}}return instance;}
}输出true
instance.hashCode=460141958
instance2.hashCode=460141958

7、静态内部类

在类加载时,静态内部类没有调用是不会进行类加载的,当被调用时才会被加载,而且只加载一次,加载时线程安全

第四章 单例模式

package tanchishell.SJMS;public class SingletonTest01 {public static void main(String[] args) {
//测试Singleton instance = Singleton.getInstance();Singleton instance2 = Singleton.getInstance();System.out.println(instance == instance2); // trueSystem.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());}
}//饿汉式(静态变量)
class Singleton {//1. 构造器私有化, 外部能 newprivate Singleton() {}//提供一个静态内部类,根据JVM底层机制保证线程安全private static class SingletonInstance{private static final Singleton INSTANCE = new Singleton();}//3. 提供一个公有的静态方法,返回实例对象public static Singleton getInstance() {Singleton instance = SingletonInstance.INSTANCE;return instance;}
}输出true
instance.hashCode=460141958
instance2.hashCode=460141958

优缺点

第四章 单例模式

8、使用枚举实现单例懒加载

第四章 单例模式

package tanchishell.SJMS;public class SingletonTest01 {public static void main(String[] args) {
//测试Singleton instance = Singleton.INSTANCE;Singleton instance2 = Singleton.INSTANCE;System.out.println(instance == instance2); // trueSystem.out.println("instance.hashCode=" + instance.hashCode());System.out.println("instance2.hashCode=" + instance2.hashCode());instance.method();}
}enum Singleton{INSTANCE;public void method(){System.out.println("hello,world");}
}输出true
instance.hashCode=460141958
instance2.hashCode=460141958
hello,world

第四章 单例模式

三、JDKの RunTime 类使用的是单例模式

第四章 单例模式
第四章 单例模式

四、单例模式注意事项和细节说明

第四章 单例模式