核心原理:
单例模式的核心是类内部实现对自身实例的唯一性和对这个实例的全局访问。通常,单例类会将其构造函数设为私有,防止外部实例化,且提供一个静态方法或属性作为全局访问点。
实现:
- 构造方法私有;
- 拥有唯一实例,且他的类变量是使用static修饰的;
懒汉式:当需要使用时候才进行实例化。(相对于饿汉式可以节约节约内存,提升加载速度,同时也要进行线程安全约束)
饿汉式:在类变量创建时候便实例化。
优点:
- 资源控制:单例模式可以控制资源消耗,避免多次创建同一对象造成的资源浪费。
- 全局访问:单例模式对象在整个应用中只有一个实例,通过全局访问点方便访问。
- 线程安全:适当的实现可以确保多线程环境下也可以正常工作,避免资源冲突。
缺点:
- 没有抽象层,扩展单例类功能困难。
- 破坏模块间的松耦合。
适用场景:
- 如果对象的创建与销毁成本较高,且在程序运行时候需要频繁访问,使用单例模式可以提供效率。
- 日常如数据库、配置管理器、日志对象这些资源通常只在应用中有一份实例。
public class Singleton_pattern {
public static void main(String[] args) {
}
}
//饿汉式(静态内部类)
class Singleton {
private static Singleton instance=new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
//懒汉式
class singleton1{
private volatile static singleton1 instance; //双重检测时候使用volatile关键词修饰(重点)
private singleton1() {}
public static singleton1 getInstance() {
if(instance==null) { //双重检测锁,第一次看未创建时候便加锁实例化(可以减小重复的范围)
synchronized (singleton1.class) {
if(instance==null) {
instance=new singleton1();
}
}
}
return instance;
}
}
/*注意问题
singletion1 = new Singleton1() 其底层可以拆分为三步
1.分配内存
2.初始化对象
3.指向刚分配的地址
由于CPU的优化运行,其执行顺序可能会变,所以当执行了1和3,但是没有执行2,线程getInstance方法会判断其并非
NULL,则会出现空指针问题,其并未指向实例对象,使用Volatile可以避免重排序。
*/