文章目录
单例模式简介
单例模式(singleton pattern)属于创建型设计模式,就是采取一定的方法保证整个软件系统中,对于某个类只存在一个实例对象。
- 一般来说单例模式有8种实现方式:
- 1-2:饿汉式(静态常量、静态代码快);
- 3-5:懒汉式(线程不安全,线程安全同步方法,线程安全同步代码块);
- 6:双重检查;
- 7: 静态内部类;
- 8:枚举类;
单例模式实现
饿汉式-静态常量
package com.xxliao.pattern.creational.singleton.type01;
/**
* @author xxliao
* @description: 单例模式-饿汉式-静态常量
*
* 实现原理:静态常量的模式基于class loader机制,避免了多线程的同步问题,在类加载的时候就进行实例初始化。
* 优点:写法简单,在类加载的时候就完成了实例化,避免了多线程的线程同步问题。
* 缺点:在类的加载时候就完成初始化,没有达到懒加载的效果,会造成一定的内存浪费。
*
* 实际开发中推荐使用
*
* @date 2024/5/23 15:59
*/
public class SingletonTest01 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1 == instance); // true
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
}
/**
* @description 饿汉式-静态常量
* @author xxliao
* @date 2024/5/23 16:00
*/
class Singleton {
// 构造私有化
private Singleton() {}
// 在本类内部创建对象实例
private final static Singleton instance = new Singleton();
// 对外提供一个公共的静态方法,用于返回实例对象
public static Singleton getInstance(){
return instance;
}
}
饿汉式-静态代码块
package com.xxliao.pattern.creational.singleton.type02;
/**
* @author xxliao
* @description: 单例模式-饿汉式-静态代码块
*
* 实现原理:静态常量的模式基于class loader机制,避免了多线程的同步问题,在类加载的时候就进行实例初始化。
* 优点:写法简单,在类加载的时候就完成了实例化,避免了多线程的线程同步问题。
* 缺点:在类的加载时候就完成初始化,没有达到懒加载的效果,会造成一定的内存浪费。
*
* 实际开发中推荐使用
*
* @date 2024/5/23 15:59
*/
public class SingletonTest02 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1 == instance); // true
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
}
/**
* @description 饿汉式-静态代码块
* @author xxliao
* @date 2024/5/23 16:00
*/
class Singleton {
// 构造私有化
private Singleton() {}
// 在本类内部创建对象实例
private final static Singleton instance;
static {
instance = new Singleton();
}
// 对外提供一个公共的静态方法,用于返回实例对象
public static Singleton getInstance(){
return instance;
}
}
懒汉式-线程不安全
package com.xxliao.pattern.creational.singleton.type03;
/**
* @author xxliao
* @description: 单例模式-懒汉式-线程不安全
*
* 优缺点: 达到了懒加载的效果,但是在多线程环境下有线程安全问题,实际开发中 不使用。
*
* @date 2024/5/23 15:59
*/
public class SingletonTest03 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1 == instance); // true
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
}
/**
* @description 懒汉式-线程不安全
* @author xxliao
* @date 2024/5/23 16:00
*/
class Singleton {
// 构造私有化
private Singleton() {}
// 在本类内部创建对象实例
private static Singleton instance;
// 对外提供一个公共的静态方法,用于返回实例对象
public static Singleton getInstance(){
if(instance == null){ // 有线程安全问题
instance = new Singleton();
}
return instance;
}
}
线程安全-同步方法
package com.xxliao.pattern.creational.singleton.type04;
/**
* @author xxliao
* @description: 单例模式-懒汉式-线程安全-同步方法
*
* 优缺点:利用synchronized关键字修饰方法,达到了线程安全的问题,但是对整个方法加锁,效率太低,实际开发中不推荐使用。
*
* @date 2024/5/23 15:59
*/
public class SingletonTest04 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1 == instance);
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
}
/**
* @description 懒汉式-线程不安全
* @author xxliao
* @date 2024/5/23 16:00
*/
class Singleton {
// 构造私有化
private Singleton() {}
// 在本类内部创建对象实例
private static Singleton instance;
// 对外提供一个公共的静态方法,用于返回实例对象
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
懒汉式-线程不安全-单一判断
package com.xxliao.pattern.creational.singleton.type05;
/**
* @author xxliao
* @description: 单例模式-懒汉式-线程不安全-单一判断
*
* 优缺点:有线程安全问题,实际开发中不使用。
*
* @date 2024/5/23 15:59
*/
public class SingletonTest05 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1 == instance);
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
}
/**
* @description 懒汉式-线程不安全
* @author xxliao
* @date 2024/5/23 16:00
*/
class Singleton {
// 构造私有化
private Singleton() {}
// 在本类内部创建对象实例
private static Singleton instance;
// 对外提供一个公共的静态方法,用于返回实例对象
public static Singleton getInstance(){
if(instance == null){// 整个判断下可能会进入多个线程,多个线程进入后,会创建多个对象。
synchronized(Singleton.class){
instance = new Singleton();
}
}
return instance;
}
}
懒汉式-线程安全-双重判断(推荐使用)
package com.xxliao.pattern.creational.singleton.type06;
/**
* @author xxliao
* @description: 单例模式-懒汉式-线程安全-双重判断
*
* 优缺点:实现了懒加载,并且没有线程安全问题,效率高,
*
* 实际开发中推荐使用。
*
* @date 2024/5/23 15:59
*/
public class SingletonTest06 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1 == instance);
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
}
/**
* @description 懒汉式-线程安全
* @author xxliao
* @date 2024/5/23 16:00
*/
class Singleton {
// 构造私有化
private Singleton() {}
// 在本类内部创建对象实例,volatile防止CPU指令重排
private static volatile Singleton instance;
// 对外提供一个公共的静态方法,用于返回实例对象
public static Singleton getInstance(){
if(instance == null){// 整个判断下可能会进入多个线程,多个线程进入后,会创建多个对象。
synchronized(Singleton.class){
if(instance == null) { // 这里再次判断,可以排除多个线程进入第一个判断后,创建多个对象情况出现。
instance = new Singleton();
}
}
}
return instance;
}
}
懒汉式-线程安全-静态内部类
package com.xxliao.pattern.creational.singleton.type07;
/**
* @author xxliao
* @description: 单例模式-懒汉式-线程安全-静态内部类
*
* 优缺点:利用了类加载机制:实例初始化只有一个线程,静态内部类在外类被加载的时候不会立即实例化,使用时候才初始化,达到了懒加载和线程安全的条件。
*
* 实际开发中推荐使用。
*
* @date 2024/5/23 15:59
*/
public class SingletonTest07 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1 == instance);
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
}
/**
* @description 懒汉式-线程安全
* @author xxliao
* @date 2024/5/23 16:00
*/
class Singleton {
// 构造私有化
private Singleton() {}
// 在本类内部创建对象实例
private static Singleton instance;
// 定义一个静态内部类,该类的一个静态属性Singleton
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
// 对外提供一个公共的静态方法,用于返回实例对象
public static Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
枚举类
package com.xxliao.pattern.creational.singleton.type08;
/**
* @author xxliao
* @description: 单例模式-枚举类
*
* 优缺点:利用枚举类是线程安全的,
*
* 实际开发中推荐使用。
*
* @date 2024/5/23 15:59
*/
public class SingletonTest08 {
public static void main(String[] args) {
Singleton instance = Singleton.INSTANCE;
Singleton instance1 = Singleton.INSTANCE;
System.out.println(instance1 == instance);
System.out.println("instance.hashCode ="+ instance.hashCode());
System.out.println("instance1.hashCode ="+ instance1.hashCode());
}
/**
* @description 枚举类
* @author xxliao
* @date 2024/5/23 16:00
*/
enum Singleton {
INSTANCE;
}
}