工厂模式(Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)
单例模式(Singleton Pattern)
原型模式(Prototype Pattern)
建造者模式(Builder Pattern)
适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
装饰器模式(Decorator Pattern)
组合模式(Composite Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
策略模式(Strategy Pattern)
观察者模式(Observer Pattern)
迭代器模式(Iterator Pattern)
命令模式(Command Pattern)
模板方法模式(Template Method Pattern)
职责链模式(Chain of Responsibility Pattern)
状态模式(State Pattern)
访问者模式(Visitor Pattern)
中介者模式(Mediator Pattern)
备忘录模式(Memento Pattern)
解释器模式(Interpreter Pattern)
单例模式(Singleton Pattern,在多线程环境下的应用)
生成器模式(Builder Pattern,在多线程环境下的应用)
保护性暂停模式(Guarded Suspension Pattern)
观察者模式(Observer Pattern,在多线程环境下的应用)
这些设计模式涵盖了对象的创建、对象间的组织和交互、以及对象的行为等方面,可以帮助开发者更好地组织和设计代码,提高代码的可扩展性、可维护性以及重用性。需要根据实际情况选择适合的设计模式来解决问题。
单例模式是设计模式中的一种,旨在确保一个类只有一个实例对象,并提供全局访问点来获取该实例。
单例模式的关键要点如下:
1.私有构造函数:为了防止外部直接创建实例,将类的构造函数设为私有。
2.静态方法或静态变量:提供一个静态方法或静态变量来获取类的唯一实例。
3.延迟实例化或饿汉式初始化:根据需要可以选择延迟实例化或在类加载时就进行初始化。
4.线程安全性:需考虑在多线程环境下保证单例对象的创建和访问的线程安全性。
5.全局访问点:提供一个全局访问点,使得任何地方都可以获取到单例实例。
同时,单例模式也有一些注意点,如可能引起全局状态的问题、对单元测试的影响等,需要权衡利弊来选择适合的使用场景。
单例模式有以下几种常见的实现方法:
1.懒汉式(Lazy Initialization):
在第一次使用时才创建实例。
线程不安全,需要考虑多线程环境下的同步问题。
可以通过双重检查锁定、同步方法等方式来实现线程安全。
2.饿汉式(Eager Initialization):
在类加载时就创建实例。
线程安全,因为实例在类加载时就已经创建。
可能会导致不必要的资源浪费,因为实例在整个程序运行期间都存在,即使不使用也会被创建。
3.静态内部类:
使用静态内部类来持有单例实例,在第一次使用时才创建实例。
线程安全,因为静态内部类在类加载时只会被加载一次,保证了实例的唯一性。
推荐使用这种方式实现单例,因为代码简洁、线程安全,且支持懒加载。
4.枚举:
枚举常量就是单例对象的实例。
线程安全,且支持序列化和反序列化,以及防止反射攻击。
推荐使用这种方式实现单例,因为代码简洁、线程安全,且具有额外的优势。
以下是一个懒汉式实现单例模式的示例(非线程安全版本):
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
// 私有的构造函数,防止外部实例化
}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
// 其他方法...
}
在这个示例中,LazySingleton类的构造函数是私有的,不允许外部直接实例化对象。getInstance()方法是懒汉式的获取单例实例的方法。在第一次调用getInstance()时,会创建一个新的实例对象并将其赋值给instance变量。之后的调用都会返回之前创建的实例对象。
需要注意的是,这个示例是非线程安全的版本,多线程环境下可能会出现竞态条件。如果多个线程同时调用getInstance()方法,并且instance还没有被初始化,那么可能会创建多个实例。为了解决这个问题,可以使用同步机制(如双重检查锁定)来确保线程安全性。
下面是一个线程安全的双重检查锁定的示例:
public class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {
// 私有的构造函数,防止外部实例化
}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
// 其他方法...
}
在这个示例中,使用了双重检查锁定来确保线程安全。通过在synchronized块内进行二次判断,可以在多线程环境下保证只有一个实例被创建。
需要注意的是,上述示例虽然解决了线程安全性问题,但在某些情况下(如高并发场景)性能可能会有一定的影响。因此,在实际使用中可以根据需求权衡利弊来选择合适的实现方式。
以下是一个饿汉式实现单例模式的示例:
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
// 私有的构造函数,防止外部实例化
}
public static EagerSingleton getInstance() {
return instance;
}
// 其他方法...
}
在这个示例中,EagerSingleton类在类加载时就创建了一个实例对象,并将其赋值给静态final的instance变量。getInstance()方法直接返回该实例,因此在任何时候调用getInstance()都会获取到同一个实例对象。
饿汉式的实现方式是在类加载时就进行实例化,因此可以保证线程安全性。由于实例在整个程序运行期间都会存在,可能会导致不必要的资源浪费。另外,需要注意的是,在某些特殊情况下可能会引起类加载的顺序问题,需要注意类加载的先后顺序。
总结来说,饿汉式是一种简单、线程安全的单例模式实现方式,适用于实例始终需要被创建且资源消耗较小的情况。但需要注意在某些特殊情况下可能引发的顺序问题。
public class Singleton {
private Singleton() {
// 私有的构造函数,防止外部实例化
}
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
// 其他方法...
}
在这个示例中,Singleton类的实例被定义为私有的静态内部类SingletonHolder的静态成员变量。通过使用静态内部类的方式,可以实现懒加载和线程安全,而无需使用显式的同步机制。
使用枚举实现单例具有以下优点:
线程安全:枚举常量的创建是线程安全的,不会被多个线程重复创建。
防止序列化和反射攻击:枚举类默认实现了Serializable接口,使用枚举实现的单例对象在序列化和反序列化时会得到正确的结果。同时,由于枚举常量有固定的实例,不会受到反射攻击。
以下是使用枚举实现单例的示例:
public enum Singleton {
INSTANCE;
public void doSomething() {
// 单例对象的方法
}
}
在这个示例中,Singleton是一个枚举类型,并且定义了一个名为INSTANCE的枚举常量,它是单例对象的唯一实例。可以通过Singleton.INSTANCE来访问这个单例对象,并调用其方法。
使用枚举实现单例模式简洁且安全,不需要担心线程安全和反射攻击的问题。因此,当需要实现单例时,可以优先考虑使用枚举来实现。
单例模式的应用有很多,例如全局资源管理、日志记录器、数据库连接池、配置管理器等。
它可以简化代码,提高资源的利用效率,并确保全局只有一个实例对象。
@作者:加辣椒了吗?
简介:憨批大学生一枚,喜欢在博客上记录自己的学习心得,也希望能够帮助到你们!