java设计模式系列-单例模式

博客围绕Java单例模式展开,指出程序员应追求写出更具拓展性、简洁的代码。介绍了单例模式的创建要素,详细分析了懒汉式(线程不安全、线程安全)、饿汉式、双重校验锁、静态内部类等多种单例模式实现方式及其优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

当工作一段时间之后,身为程序员也要对自己写的代码有所要求,无论是为了满足部门codereview的要求,还是为了自己的代码看起来更加优雅,写出更有拓展性、简洁的代码都应该是我们所追求的目标之一。
:由于本人的能力有限,多多少少会借鉴其他好的文章的一些描述,望见谅。

单例模式

本文介绍的是单例模式,创建单例模式需要一个私有的构造器(不能直接new来获取实例)、一个私有的静态变量、一个公有的静态函数(对外提供获取实例的方法)

  1. 懒汉式单例 - 线程不安全

    虽然可以做到uniqueInstance变量的延迟实例化,但是多线程下是不安全的。

    public class Singleton1 {
    
    private static Singleton1 uniqueInstance;
    
    private Singleton1() {
    }
    
    public static Singleton1 getInstance() {
        if (uniqueInstance != null) {
            return new Singleton1();
        } else {
            return uniqueInstance;
        }
     }
    }
    
  2. 饿汉式-线程安全
    采用直接实例化避免了多线程下被多次实例

    public class Singleton2 {
    
     private static Singleton2 uniqueInstance = new Singleton2();
    
     private Singleton2 getInstance() {
        return uniqueInstance;
     }
    }
    

    这种情况不是延迟加载,所以对于性能可能会有影响,虽然我觉得影响并不大,但是还是有其他更好的办法来解决性能问题,接着看。

  3. 懒汉式-线程安全
    常见的对获取实例的方法加锁,但是同样是有性能问题,如果多个线程同时访问改方法,可能会造成阻塞时间过长。

    public class Singleton3 {
    
        private static Singleton3 uniqueInstance;
    
        public static synchronized Singleton3 getInstance() {
            if (uniqueInstance != null) {
                return uniqueInstance;
            } else {
                return new Singleton3();
            }
        }
    }
    
  4. 双重校验锁-线程安全

    双重校验锁先判断 uniqueInstance 是否已经被实例化,如果没有被实例化,那么才对实例化语句进行加锁。volatile关键字的作用主要是禁止在多线程情况下指令重排序,volitile的作用可以参看这篇文章:https://www.cnblogs.com/dolphin0520/p/3920373.html

    public class Singleton4 {

      private volatile static Singleton4 uniqueInstance;
    
      private Singleton4(){}
    
      public static Singleton4 getUniqueInstance() {
    
      if (uniqueInstance == null) {
          synchronized (Singleton4.class) {
              if (uniqueInstance == null) {
                  return new Singleton4();
              }
          }
      }
      return uniqueInstance;
      }
    }
    

5.静态内部类
因为静态内部类(SingletonHolder )只有在被调用的时候才会加载,所以保证了延迟加载,同时INSTANCE变量是静态的,通过JVM保证了线程的安全。

public class Singleton5 {

	private Singleton5(){}

	/**
	 * 静态内部类只有在被调用的时候才会加载,与静态方法一样
 	*/
	public static class SingletonHolder {
    	private static final Singleton5 uniqueInstance = new Singleton5();
    }

    public static Singleton5 getInstance() {
    	return SingletonHolder.uniqueInstance;
	}
}

源代码:https://github.com/DadySu/HeadFirst/tree/master/src/singletonpattern

朋友,再会!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值