-
Notifications
You must be signed in to change notification settings - Fork 26.6k
Description
Pre-check
- I am sure that all the content I provide is in English.
Search before asking
- I had searched in the issues and found no similar issues.
Apache Dubbo Component
Java SDK (apache/dubbo)
Dubbo Version
Dubbo 3.3.x (Confirmed in latest master branch) & Dubbo 2.7.x.
JDK 1.8+, All Operating Systems.
Steps to reproduce this issue
- This issue is identified via static code analysis (concurrency safety check).
- It is located in
org.apache.dubbo.registry.nacos.NacosRegistrymethodscheduleServiceNamesLookup. - The method uses a "Check-Then-Act" pattern to lazily initialize the
scheduledExecutorService. - Although the field is
volatile, the initialization block is NOT synchronized.
Code Analysis:
When scheduleServiceNamesLookup is called concurrently (e.g. via admin protocol), a race condition occurs:
if (scheduledExecutorService == null) { // Thread A and B can pass here simultaneously
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); // Executed twice
// ...
}
What you expected to happen
The scheduledExecutorService should be initialized as a Singleton in a thread-safe manner (e.g., using Double-Checked Locking). Only one thread pool should be created to avoid thread leaks.
Anything else
Proposed Solution (Double-Checked Locking)
I suggest modifying the code to use synchronized DCL:
private void scheduleServiceNamesLookup(final URL url, final NacosAggregateListener listener) {
if (scheduledExecutorService == null) {
synchronized (this) {
if (scheduledExecutorService == null) {
// Recommend naming the thread for better debuggability
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(
new NamedThreadFactory("Dubbo-Nacos-Registry-Scheduler", true)
);
scheduledExecutorService.scheduleAtFixedRate(
() -> {
// ... existing logic ...
},
LOOKUP_INTERVAL,
LOOKUP_INTERVAL,
TimeUnit.SECONDS);
}
}
}
}
Are you willing to submit a pull request to fix on your own?
- Yes I am willing to submit a pull request on my own!
Code of Conduct
- I agree to follow this project's Code of Conduct
Metadata
Metadata
Assignees
Labels
Type
Projects
Status