单例模式

本文深入解析单例模式的概念、作用及其实现方式,包括懒汉式和饿汉式的区别,并探讨了多线程环境下单例模式的实现,还介绍了静态内部类和枚举方式的单例模式。

单例模式

1.1什么是单例

在程序运行中,只允许一个实例,不允许创建多个实例,这就称为单例。

1.2 单例设计模式的作用

在实际开发中,在系统或平台中中允许一个实例对象,这时就需用到单例模式。(例如,一个朝代只允许一个皇帝)

1.3单例模式原理

通过私有化构造方法,向外提供一个公开的方法获取实例
分析:

  • 某个类只能有一个对象,但是构造方法只要一调用就会产生新的对象,可以通过封装将构造方法进行私有化;
  • 若构造方法私有化,那么此类在外部不能创建对象,需要再类内部创建对象;
  • 添加一个公开的方法,返回这个对象。
1.4实现方式

实现方式:
单例分为懒汉式和饿汉式
核心:
构造方法私有:不能在类外随意创建对象
在类内部声明一个本类静态的对象作为属性
提供一个共有静态的方法用来获取本类对象

饿汉式实现代码

public class Boss{
	//属性
	private String name;
	private int age;
	//私有化构造方法
	private Boss(String name, int age){
		this.name = name;
		this.age = age;
	}
	//私有静态本类对象作为属性
	private static Boss boss = new Boss("马云",12);
	//提供共有静态方法获取本类对象
	public static Boss getBoss(){
		return boss;
	}
}

懒汉式实现代码

pulbic class King{
	//属性
	private String name;
	private int age;
	//私有构造方法
	private King(String name, int age){
		this.name = name;
		this.age = age;
	}
	//私有静态本类对象
	private static King king;
	//共有静态方法获取本类对象
	public static King getKing(){
		if(king==null){
			king = new King("唐太宗",12);
		}
		return king;
	}
}

思考:懒汉式和饿汉式有什么区别?
语法区别:懒汉是调用方法时初始化对象,饿汉是声明同时初始化
存储空间:在第一次获取单例类对象前,懒汉比饿汉节省空间
多线程操作时区别:懒汉式存在线程安全问题,饿汉式没有线程安全问题

多线程单例模式

由于饿汉式没有线程安全问题,这里就不再演示,主要讲解一下懒汉式。

2.1懒汉式

实现代码:

/**
 * 单例
 *
 */
public class SingleTon {
	private SingleTon(){
		 //禁止反射破解
        synchronized (SingleTon.class) {
            if (instance != null) {
                throw new RuntimeException("不能使用反射创建对象");
            }
        }
	}
	private static volatile SingleTon instance; //volatile:不稳定的,易挥发的
	
	public static SingleTon getInstance() {
		if(singleTon==null) {//为了提高效率
			synchronized (SingleTon.class) {//判断锁的过程比较耗性能,为了提高效率
				if (singleTon == null) {
					singleTon = new SingleTon();
				}
			}
		}
		return singleTon;
	}
	
}

/**
 * 线程类
 * @author wgy
 *
 */
public class SingleTonThread extends Thread{
	@Override
	public void run() {
		SingleTon singleTon=SingleTon.getInstance();
		System.out.println(singleTon.hashCode());
	}
}


package com.qf.day20_6;

public class Test {
	public static void main(String[] args) {
		//线程对象
		SingleTonThread s1=new SingleTonThread();
		SingleTonThread s2=new SingleTonThread();
		SingleTonThread s3=new SingleTonThread();
		//启动线程
		s1.start();
		s2.start();
		s3.start();
		
	}
}

其他方式实现单例模式

3.1静态内部类写法
/*
 * 静态内部类写法
 * (1)节省空间
 * (2)不会线程安全问题
 */
public class SingleTon2 {
    private SingleTon2(){

    }

    static class Holder{
        private static final SingleTon2 INSTACNE=new SingleTon2();
    }

    public static SingleTon2 getInstance(){
        return Holder.INSTACNE;
    }
    
}

优点:
(1)节省空间 (2)不会线程安全问题

3.2枚举方式
/*
 * 枚举写法
 * (1)没有线程安全问题
 * (2)反射破解问题
 *
 */
public enum  SingleTon3 {
    INSTANCE;
    public static SingleTon3 getInstance(){
        return INSTANCE;
    }
}

优点:

  • (1)没有线程安全问题
  • (2)反射破解问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值