Java Singleton类中的线程安全性的示例代码

 

Java Singleton类中的线程安全性的示例代码

 

Singleton是最广泛使用的创建设计模式之一,用于限制应用程序创建对象。在实际应用程序中,数据库连接或企业信息系统(EIS)等资源是有限的,应该明智地使用以避免任何资源紧缩。为此,我们可以实现Singleton设计模式来创建围绕资源的包装类,并将在运行时创建的对象数限制为一个。

 

Java中的线程安全单例

线程安全单例,java中的线程安全单例
一般来说,我们按照以下步骤创建一个单例类:

  1. 重写私有构造函数以避免使用new运算符创建任何新对象。
  2. 声明同一个类的私有静态实例
  3. 提供一个公共静态方法,它将返回单例类实例变量。如果未初始化变量,则初始化它,否则只返回实例变量。

使用上面的步骤,我创建了一个单独的类,如下所示:

ASingleton.java


package com.journaldev.designpatterns;

public class ASingleton {

	private static ASingleton instance = null;

	private ASingleton() {
	}

	public static ASingleton getInstance() {
		if (instance == null) {
			instance = new ASingleton();
		}
		return instance;
	}

}

在上面的代码中,getInstance()方法不是线程安全的。多个线程可以同时访问它,对于前几个线程,当实例变量未初始化时,多个线程可以进入if循环并创建多个实例并打破我们的单例实现。

有三种方法可以实现线程安全。

  1. 在类加载时创建实例变量。

    优点

    • 线程安全无需同步
    • 易于实施

    缺点

    • 早期创建可能未在应用程序中使用的资源。
    • 客户端应用程序无法传递任何参数,因此我们无法重用它。例如,具有用于数据库连接的通用单例类,其中客户端应用程序提供数据库服务器属性。
  2. 同步getInstance()方法

    优点

    • 线程安全性得到保证。
    • 客户端应用可以传递参数
    • 实现了懒惰初始化

    缺点

    • 由于锁定开销导致性能下降。
    • 初始化实例变量后不需要的不必要的同步。
  3. 在if循环和volatile变量中使用synchronized块

    优点

    • 线程安全性得到保证
    • 客户端应用可以传递参数
    • 实现了懒惰初始化
    • 同步开销很小,仅当变量为null时才适用于前几个线程。

    缺点

    • 额外的条件

看看实现线程安全的所有三种方法,我认为第三种方法是最佳选择,在这种情况下,修改后的类将如下所示:


package com.journaldev.designpatterns;

public class ASingleton {

	private static volatile ASingleton instance;
	private static Object mutex = new Object();

	private ASingleton() {
	}

	public static ASingleton getInstance() {
		ASingleton result = instance;
		if (result == null) {
			synchronized (mutex) {
				result = instance;
				if (result == null)
					instance = result = new ASingleton();
			}
		}
		return result;
	}

}

局部变量result似乎没必要。但它可以提高我们代码的性能。在实例已经初始化的情况下(大多数情况下),volatile字段只被访问一次(由于“return result;”而不是“return instance;”)。这可以将方法的整体性能提高多达25%。

如果您认为有更好的方法可以实现这一点,或者上述实施中的线程安全性受到影响,请发表评论并与我们所有人分享。

更新:String不是用于同步的非常好的候选者,因此我使用Object更新了它,了解有关java中的同步和线程安全的更多信息。

 

转载来源:https://www.journaldev.com/1827/java-design-patterns-example-tutorial 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值