本文将讨论在 Java 中实现线程安全的延迟初始化。
延迟初始化是延迟对象创建的行为。 它还可能导致某些计算任务或首次昂贵流程的延迟。
Java 中有两种类型的对象初始化。 它们是急切初始化和惰性初始化。
在 Eager 初始化中,对象初始化发生在编译时。 如果过程很长,这会消耗时间和内存。
在延迟初始化中,对象初始化在程序需要时发生。 因此它可以节省内存、增强处理能力并提高效率。
线程是可以并行运行进程以优化时间的次要组件。 线程安全是一个 Java 类,可确保类的内部状态和函数在多个线程同时调用期间返回的值的正确性。
getter 方法检查私有成员是否已经具有某些值。 如果有,该函数返回它; 否则,它会创建一个新实例并在第一次执行时返回它。
有两种方法可以进行延迟初始化。
- 在函数名称之前使用synchronize 关键字。
- 使用双重检查锁定或同步块方法。
当多个线程并行运行时,变量可能会返回意外结果。 这里,我们需要一个线程安全的代码来防止Java中的死锁。
例子:
考虑一家银行,其中只有一个代币计数器可用于代币分配。 这里的任务是仅当客户进来时创建一个 Bank 类; 该过程是惰性初始化。
让我们创建多个线程,例如 t1、t2 等,以了解多线程调用。 每个线程都是一个客户。
当客户来获取代币时,我们创建一个 Bank 对象,并在函数参数中使用代币编号调用 。 现在,显示令牌是否可用并指定消息中的下一个操作。
如果有token,则发行token; 否则,请继续接待下一位顾客。
该程序解释了 和 。 我们可以使用Thread.sleep来保证输出的准确性。
在此示例中,我们有两个客户线程。
变量检查实例是否为空。 如果变量为空,程序将创建一个实例。
空标志检查令牌是否可用。 如果令牌可用,则标志值为 true。
将令牌提供给客户后,程序将标志值设置为 false。 因此,在 完成之前,下一个客户将不会获得令牌。
示例代码:
输出:
在上面的输出中,用户可以观察到两个客户实例是并行出现的。 因此,第一个实例获取令牌,第二个实例获取消息。
在此示例中,我们创建两个客户线程。 变量两次检查实例是否为 null,并且方法 返回新实例。
标志empty的值决定了令牌的可用性。 如果该标志为真,则该令牌可供客户使用。
客户获得令牌后,该标志变为 false。 在当前线程完成其操作之前,运行多个线程无法更改任何值。
示例代码:
输出1:
请注意,当两个客户实例并行到达时,程序将令牌提供给第一个实例并通知第二个客户。
输出2:
这里,token对于客户2来说是不可用的,原因是在 之前缺少 。 客户 1 获得令牌,因为 在 之前运行。
本教程教给我们两种在 Java 中实现线程安全延迟初始化的方法。 第一种方法使用 synchronized 关键字,第二种方法是 synchronized 块方法。
同步块方法确保了双重检查。 用户可以根据上下文选择任何一种方式。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/8152.html