Java单例设计模式实践与示例

在里面 以前的 文章中,我们讨论了单例设计模式和单例类 实施 详细地 在本文中,我们将看到如何创建单例类。阅读本文后,您将能够根据自己的用途、简单性和消除的瓶颈创建singleton类。 在Java中有很多方法可以做到这一点。所有这些方式在模式的实现上都有所不同,但最终,它们都实现了单个实例的相同最终结果。

null
  1. 快速初始化: 这是创建单例类的最简单方法。在这种情况下,类的对象是在JVM将其加载到内存时创建的。这是通过直接将引用分配给实例来完成的。 当程序总是使用这个类的实例,或者创建实例的成本在资源和时间方面不是太大时,可以使用它。

JAVA

// Java code to create singleton class by
// Eager Initialization
public class GFG
{
// public instance initialized when loading the class
private static final GFG instance = new GFG();
private GFG()
{
// private constructor
}
public static GFG getInstance(){
return instance;
}
}


  1. 赞成的意见:
    1. 实现起来非常简单。
    2. 可能导致资源浪费。因为不管是否需要,类的实例总是被创建的。
    3. 如果不需要,CPU时间也会浪费在实例的创建上。
    4. 异常处理是不可能的。
  2. 使用静态块: 这也是即时初始化的一个子部分。唯一的区别是对象是在静态块中创建的,这样我们就可以访问它的创建,比如异常处理。同样,对象也是在类加载时创建的。 它可以在创建具有急切初始化的对象时出现异常时使用。

JAVA

// Java code to create singleton class
// Using Static block
public class GFG
{
// public instance
public static GFG instance;
private GFG()
{
// private constructor
}
static
{
// static block to initialize instance
instance = new GFG();
}
}


  1. 赞成的意见:
    1. 实现起来非常简单。
    2. 不需要实现getInstance()方法。实例可以直接访问。
    3. 异常可以在静态块中处理。
    4. 可能导致资源浪费。因为不管是否需要,类的实例总是被创建的。
    5. 如果不需要,CPU时间也会浪费在实例的创建上。
  2. 延迟初始化: 在这种方法中,仅当需要时才创建对象。这可以防止资源浪费。需要一个getInstance()方法的实现来返回实例。有一个空检查,如果对象没有创建,那么创建,否则返回之前创建的。为了确保类不能以任何其他方式实例化,构造函数被设置为final。当在方法中使用创建对象时,它确保在需要时才会创建对象。实例是私有的,因此没有人可以直接访问它。 它可以在单线程环境中使用,因为多个线程可以破坏singleton属性,因为它们可以同时访问get instance方法并创建多个对象。

JAVA

//Java Code to create singleton class
// With Lazy initialization
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
//method to return instance of class
public static GFG getInstance()
{
if (instance == null )
{
// if instance is null, initialize
instance = new GFG();
}
return instance;
}
}


  1. 赞成的意见:
    1. 对象仅在需要时创建。它可以克服资源不足和CPU时间浪费的问题。
    2. 方法中也可以进行异常处理。
    3. 每次都必须检查null的条件。
    4. 实例无法直接访问。
    5. 在多线程环境中,它可能会破坏singleton属性。
  2. 线程安全单例: 在中创建线程安全的singleton,以便即使在多线程环境中也能维护singleton属性。为了使单例类线程安全,getInstance()方法被同步,以便多个线程不能同时访问它。

JAVA

// Java program to create Thread Safe
// Singleton class
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
//synchronized method to control simultaneous access
synchronized public static GFG getInstance()
{
if (instance == null )
{
// if instance is null, initialize
instance = new GFG();
}
return instance;
}
}


  1. 赞成的意见:
    1. 延迟初始化是可能的。
    2. 它也是线程安全的。
    3. getInstance()方法是同步的,因此由于多个线程无法同时访问它,因此会导致性能降低。
  2. 具有双重检查锁定的延迟初始化: 在这种机制中,我们克服了同步代码的开销问题。在这个方法中,getInstance是不同步的,但是创建实例的块是同步的,所以等待的线程数最少,这只是第一次。

JAVA

// Java code to explain double check locking
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
public static GFG getInstance()
{
if (instance == null )
{
//synchronized block to remove overhead
synchronized (GFG. class )
{
if (instance== null )
{
// if instance is null, initialize
instance = new GFG();
}
}
}
return instance;
}
}


  1. 赞成的意见:
    1. 延迟初始化是可能的。
    2. 它也是线程安全的。
    3. 由于同步关键字,性能开销降低。
    4. 第一次,它会影响性能。
  2. Bill Pugh Singleton实现: 在Java5之前,内存模型有很多问题,在多线程环境中,上述方法在某些情况下会导致失败。因此,Bill Pugh提出了一个用于singleton的内部静态类的概念。

JAVA

// Java code for Bill Pugh Singleton Implementation
public class GFG
{
private GFG()
{
// private constructor
}
// Inner class to provide instance of class
private static class BillPughSingleton
{
private static final GFG INSTANCE = new GFG();
}
public static GFG getInstance()
{
return BillPughSingleton.INSTANCE;
}
}


  1. 加载singleton类时,不会加载内部类,因此在加载类时不会创建对象。内部类仅在调用getInstance()方法时创建。因此,它可能看起来像是热切的初始化,但它是懒惰的初始化。 这是使用最广泛的方法,因为它不使用同步。

什么时候用什么

  1. 即时初始化很容易实现,但可能会造成资源和CPU时间浪费。仅当初始化类的成本在资源方面较低,或者您的程序总是需要类的实例时,才使用它。
  2. 通过在即时初始化中使用静态块,我们可以提供异常处理,也可以控制实例。
  3. 使用synchronized,我们也可以在多线程环境中创建单例类,但它会导致性能降低,所以我们可以使用双重检查锁定机制。
  4. Bill Pugh实现是单例类最广泛使用的方法。大多数开发人员喜欢它,因为它的简单性和优势。

本文由 维沙尔·加格 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享