Skip to content

(#4884) Replaced synchronized with ReentrantLock in PhOnce#4914

Open
AlexNetTie wants to merge 5 commits intoobjectionary:masterfrom
AlexNetTie:issue-4884-reentrantlock
Open

(#4884) Replaced synchronized with ReentrantLock in PhOnce#4914
AlexNetTie wants to merge 5 commits intoobjectionary:masterfrom
AlexNetTie:issue-4884-reentrantlock

Conversation

@AlexNetTie
Copy link
Copy Markdown
Contributor

@AlexNetTie AlexNetTie commented Mar 5, 2026

What does this PR do?

Replaces synchronized block with ReentrantLock in PhOnce constructor to avoid blocking the whole object during lazy initialization and to comply with qulice rules.

Related issues

Changes

  • Added ReentrantLock field
  • Replaced synchronized (this.ref) with lock.lock() / lock.unlock() in try-finally block
  • Removed corresponding @todo puzzle
  • Preserved all existing functionality

How to test

Run mvn clean install -pl eo-runtime -am to verify the module compiles. The change is internal and should not affect existing behavior.

Summary by CodeRabbit

  • Refactor
    • Improved internal synchronization and initialization to make concurrency handling more robust.
    • Strengthened atomic creation of internal resources for more reliable startup under concurrent use.
    • Preserves all public APIs and observable behavior.
    • No user-facing changes; improvements confined to internal implementation.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8ee79187-8c58-4e2e-81d9-f59ea7bfe01e

📥 Commits

Reviewing files that changed from the base of the PR and between 82ed82c and 59cf449.

📒 Files selected for processing (1)
  • eo-runtime/src/main/java/org/eolang/PhOnce.java

📝 Walkthrough

Walkthrough

Replaced the synchronized initialization in PhOnce with a ReentrantLock field; the lock is created in the constructor and used to guard the cached ref lazy initialization via explicit lock.lock() / lock.unlock(). No public API or signature changes. (34 words)

Changes

Cohort / File(s) Summary
Synchronization refactor
eo-runtime/src/main/java/org/eolang/PhOnce.java
Added import java.util.concurrent.locks.ReentrantLock;, introduced private final ReentrantLock lock;, initialized it in the constructor, and replaced the synchronized block around the cached ref with lock.lock() / lock.unlock() for atomic lazy initialization. Removed previous PMD/suppression comments; minor formatting tweak in a lambda.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nudged the threads where shadows play,
Replaced a sync with a lock today,
My paws now guard the lazy seed,
No more races, steady speed,
Hop on — the code sleeps safe and gay.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: replacing synchronized with ReentrantLock in the PhOnce class.
Linked Issues check ✅ Passed The PR implements a targeted refactor to replace synchronized blocks with ReentrantLock in PhOnce to comply with qulice 0.25.1 rules, directly addressing the upgrade requirement in issue #4884.
Out of Scope Changes check ✅ Passed All changes are scoped to the PhOnce class and directly support the qulice 0.25.1 compliance objective; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
eo-runtime/src/main/java/org/eolang/PhOnce.java (1)

45-53: Consider a fast path to avoid locking after initialization.

Line 45 currently acquires the lock on every access, even when ref is already initialized. A pre-check + in-lock recheck keeps correctness while reducing contention on hot paths.

♻️ Suggested refactor
         this.object = () -> {
-            lock.lock();
-            try {
-                if (this.ref.get() == null) {
-                    this.ref.set(obj.get());
-                }
-                return this.ref.get();
-            } finally {
-                lock.unlock();
-            }
+            Phi cached = this.ref.get();
+            if (cached == null) {
+                this.lock.lock();
+                try {
+                    cached = this.ref.get();
+                    if (cached == null) {
+                        cached = obj.get();
+                        this.ref.set(cached);
+                    }
+                } finally {
+                    this.lock.unlock();
+                }
+            }
+            return cached;
         };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eo-runtime/src/main/java/org/eolang/PhOnce.java` around lines 45 - 53, PhOnce
currently always acquires the lock on every access; add a fast-path null check
to return this.ref.get() immediately when already initialized, then perform the
existing lock + in-lock recheck to set ref only if still null (i.e., in the
method containing lock.lock()/lock.unlock() replace the unconditional lock with:
if (this.ref.get() != null) return this.ref.get(); lock.lock(); try { if
(this.ref.get() == null) this.ref.set(obj.get()); return this.ref.get(); }
finally { lock.unlock(); }). Ensure you reference the PhOnce class, the ref
field, the lock and the supplier parameter (obj) so the semantics remain
identical while reducing contention.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@eo-runtime/src/main/java/org/eolang/PhOnce.java`:
- Around line 45-53: PhOnce currently always acquires the lock on every access;
add a fast-path null check to return this.ref.get() immediately when already
initialized, then perform the existing lock + in-lock recheck to set ref only if
still null (i.e., in the method containing lock.lock()/lock.unlock() replace the
unconditional lock with: if (this.ref.get() != null) return this.ref.get();
lock.lock(); try { if (this.ref.get() == null) this.ref.set(obj.get()); return
this.ref.get(); } finally { lock.unlock(); }). Ensure you reference the PhOnce
class, the ref field, the lock and the supplier parameter (obj) so the semantics
remain identical while reducing contention.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e139a486-0241-4a2d-80d6-b677eef3fafb

📥 Commits

Reviewing files that changed from the base of the PR and between 9250c27 and ac79d26.

📒 Files selected for processing (1)
  • eo-runtime/src/main/java/org/eolang/PhOnce.java

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eo-runtime/src/main/java/org/eolang/PhOnce.java`:
- Around line 44-58: The Supplier<Phi> lambda assigned to this.object in
PhOnce.java currently never returns a Phi; inside the supplier (which reads
cached via this.ref, locks this.lock, calls obj.get(), sets this.ref) add a
final "return cached;" just before the lambda ends so the Supplier<Phi> returns
the computed Phi value (ensure the returned variable is the same cached used
after obj.get()/this.ref.set()).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c6e91ffe-08c5-4536-b1c3-0574d52e0f3e

📥 Commits

Reviewing files that changed from the base of the PR and between ac79d26 and e1656c6.

📒 Files selected for processing (1)
  • eo-runtime/src/main/java/org/eolang/PhOnce.java

Comment thread eo-runtime/src/main/java/org/eolang/PhOnce.java
…ocking

The previous implementation didn't store the result in a local variable,
causing unnecessary lock acquisition after initialization. Now using
standard DCL pattern with local cached variable for better performance.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 5, 2026

🚀 Performance Analysis

All benchmarks are within the acceptable range. No critical degradation detected (threshold is 100%). Please refer to the detailed report for more information.

Click to see the detailed report
Test Base Score PR Score Change % Change Unit Mode
benchmarks.XmirBench.xmirToEO 213.218 216.780 3.562 1.67% ms/op Average Time

⚠️ Performance loss: benchmarks.XmirBench.xmirToEO is slower by 3.562 ms/op (1.67%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

qulice 0.25.1 Upgrade Causes Massive Changes in Codebase

1 participant