fix: replace busy-wait loop in BallThread with wait/notify (#2977) - #3614
KANISHKMAKKAR wants to merge 2 commits into
Conversation
PR SummaryRefactored BallThread to replace the busy-wait loop with a wait/notify pattern guarded by a private lock. suspendMe() now sets Changes
autogenerated by presubmit.ai |
There was a problem hiding this comment.
✅ LGTM!
Review Summary
Commits Considered (2)
Files Processed (2)
- twin/README.md (1 hunk)
- twin/src/main/java/com/iluwatar/twin/BallThread.java (2 hunks)
Actionable Comments (0)
Skipped Comments (6)
-
twin/src/main/java/com/iluwatar/twin/BallThread.java [39-39]
best_practice: "Introduce a dedicated synchronization lock for suspend/resume"
-
twin/src/main/java/com/iluwatar/twin/BallThread.java [50-55]
best_practice: "Guard suspend state with wait loop"
-
twin/src/main/java/com/iluwatar/twin/BallThread.java [68-70]
best_practice: "Synchronize suspendMe state update"
-
twin/src/main/java/com/iluwatar/twin/BallThread.java [75-78]
best_practice: "Wake up thread on resume"
-
twin/src/main/java/com/iluwatar/twin/BallThread.java [83-87]
enhancement: "Ensure stop notifies waiting thread"
-
twin/README.md [91-93]
best_practice: "README aligns with implementation"
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3614 +/- ##
============================================
- Coverage 84.06% 84.01% -0.05%
+ Complexity 4353 4351 -2
============================================
Files 1133 1133
Lines 15400 15413 +13
Branches 739 740 +1
============================================
+ Hits 12946 12950 +4
- Misses 2158 2164 +6
- Partials 296 299 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Addresses item 2 (
Twin / BallThread.java) of #2977.Problem
While suspended,
BallThreadwakes every 250 ms only to re-checkisSuspendedand do nothing. BecauseresumeMe()merely flips the flag, it has no way to wake the sleeping thread, so resuming is delayed until the current sleep tick expires.stopMe()has the same weakness.Change
isSuspendedis now guarded by a private lock. The run loop waits on that lock while suspended, andresumeMe()/stopMe()callnotifyAll(). Polling is replaced by blocking, and resume takes effect immediately.The
Thread.sleep(250)animation pacing is intentional and left unchanged.Result
Latency from
resumeMe()to the firstdraw(), averaged over 5 runs:Notes
BallThreadTest(suspend / resume / interrupt) passes unmodified, including theverifyNoMoreInteractionsassertions and theRuntimeException-on-interrupt check.notifyAll()instopMe()is required: without it, stopping an already-suspended thread would block forever inwait().twin/README.mdembeds this class verbatim, so it is updated to match.Retryclasses use deliberate backoff sleeps rather than busy-waiting.