You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Lock Object实现单例与经典双重检查锁单例的差异及锁对象作用解析

Great question! Let's break down the core differences between these two singleton implementations and unpack the thinking behind using a dedicated lock object.

Key Differences Between the Two Implementations

1. Locking Behavior & Performance

Your implementation uses eager locking: every call to getEntryPoint() acquires the lock first, even after the entryPoint instance is already initialized. This means every subsequent call has to wait for the lock to be released, adding unnecessary overhead once the singleton is fully ready.

The classic double-checked locking (DCL) implementation is optimized for performance: it first checks if entryPoint is null without locking. Only if the instance doesn't exist does it enter the synchronized block. After initialization, all future calls skip the lock entirely, making it much faster for repeated access.

2. Lock Target Isolation

  • Your code uses a dedicated LOCK_OBJECT as the synchronization target. This lock is only used within this singleton initialization logic, keeping its scope tightly controlled.
  • The classic DCL uses Service.class as the lock. Since the class object is a global resource, any other code in your application that also synchronizes on Service.class will compete for the same lock, potentially causing unexpected blocking and bottlenecks.

3. Initialization Safety Requirements

  • In your implementation, every access is wrapped in a synchronized block, so you don't need to mark entryPoint as volatile. The lock itself ensures all threads see the most up-to-date value of entryPoint.
  • The classic DCL requires entryPoint to be marked volatile (in Java 5+). Without volatile, the JVM might reorder the initialization steps of Service, leading to threads seeing a partially initialized instance of entryPoint.
Design Rationale Behind the Dedicated Lock Object

Using a dedicated LOCK_OBJECT instead of the class object has three key benefits:

  • Eliminate Cross-Code Lock Contention: As mentioned earlier, other parts of your codebase that use Service.class for synchronization won't interfere with your singleton's initialization logic. This isolates lock scopes and prevents unintended slowdowns.
  • Clearer Code Intent: A named lock object like LOCK_OBJECT makes it immediately obvious to other developers that this lock exists solely to protect the singleton's initialization. Using Service.class is more ambiguous—readers might wonder if the lock is used elsewhere in the class.
  • Future Flexibility: If you ever need to switch to a more advanced locking mechanism (like java.util.concurrent.locks.ReentrantLock), having a dedicated object makes this refactor much easier. You won't have to untangle dependencies on the class object as a lock.

内容的提问来源于stack exchange,提问作者kamil.rak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:48:27