Java 单例模式是一种创建设计模式,是四种设计模式的帮派之一。单例设计模式是创建对象的最佳方法之一。它似乎是一个基于定义的相对简单的设计模式。但是,在实施方面,存在几个实施问题。 Java Singleton 模式的使用长期以来一直是程序员之间有争议的问题。
单个类负责以这种模式创建一个对象,同时确保只创建一个对象。
单例意味着每个容器一个实例。例如,如果程序是用 Java 编写的,则为 JVM 提供一个实例。
违反单例设计模式的共同原则:在实现单例时,创建实例时不应带任何参数。
单例你不应该矫枉过正,因为单元测试真的很难。因为没有实例变量,也没有任何其他要创建的引用。因此,单元测试真的很难。单例不应该在任何地方使用。需要时必须使用单例。
我们将通过一个代码示例来了解单例模式。
SingleObject.Java
public class SingleObject {
private static volatile SingleObject singleObject = new SingleObject();
private SingleObject() {
}
public static SingleObject getSingleObject() {
return singleObject;
}}Singleton.java
public class Singleton {
public static void main(String[] args) {
SingleObject singleObject = SingleObject.getSingleObject();
System.out.println(singleObject);
SingleObject singleObject1 = SingleObject.getSingleObject();
System.out.println(singleObject);
}}Actual Output:
SingleObject@6504e3b2
SingleObject@6504e3b2在上面的代码片段中,我们分配了两个单独的变量,在不同的时间调用它们,并接收到相同的实例。
不用多说,如果我们调整如下所示的代码呢?
public class SingleObject {
private static volatile SingleObject singleObject;
private SingleObject() {
if(singleObject !=null) {
throw new RuntimeException("Please use getSingleObject Method");
}}
public static SingleObject getSingleObject() {
if(singleObject==null) {
singleObject=new SingleObject();
}
return singleObject;
}}修改 SingleObject 后我们得到了相同的结果,因为它是之前构造的; 它返回了相同的实例。 但是这里有个问题,
让我们假设 thread1 通过 if(singleObject == null) 行并检查它的 null 并将值分配给这个 singleObject 变量。 因此,与此同时,thread2 出现并排队 if(singleObject == null) 并询问“is singleObject is null”,因此尚未创建 thread1,它正在创建中。 自 thread1 创建以来,它告诉我们的是“它是空的”。 所以thread2也进来了。这意味着这不是线程安全的。
为了防止这个问题,我们可以改变 SingleObject 类如下。
public class SingleObject {
private static volatile SingleObject singleObject;
private SingleObject() {
if(singleObject !=null) {
throw new RuntimeException("Please use getSingleObject Method");
}}
public static SingleObject getSingleObject() {
if(singleObject==null) {
synchronized (SingleObject.class) {
if(singleObject == null) {
singleObject=new SingleObject();
}}}
return singleObject;
}}现在在这里 thread1 来到 if(singleObject == null) 行,所以它是 null 并转到行 synchronized(SingleObject.class){} 并获取锁。 然后再次进入 if(singleObject == null),是的,它是 null。 现在 thread1 创建一个实例。 同时 thread2 检查 singleObject 是否为 null,是的,它为 null,因为 thread1 仍在创建。 然后转到 synchronized(SingleObject.class){},上面写着“你不允许进入,因为里面已经有一个人正在处理这个问题,所以请在外面等一下”。 所以现在发生的事情是thread2离开然后同步块允许第二个进入并继续创建实例。
感谢您的阅读! 如果你喜欢,请留下一个掌声并关注我的页面。
关注七爪网,获取更多APP/小程序/网站源码资源!
| 留言与评论(共有 0 条评论) “” |