Skip to content

fix: replace busy-wait loop in BallThread with wait/notify (#2977) - #3614

Open
KANISHKMAKKAR wants to merge 2 commits into
iluwatar:masterfrom
KANISHKMAKKAR:fix-2977-ballthread-busy-wait
Open

KANISHKMAKKAR wants to merge 2 commits into
iluwatar:masterfrom
KANISHKMAKKAR:fix-2977-ballthread-busy-wait

Conversation

@KANISHKMAKKAR

Copy link
Copy Markdown

Addresses item 2 (Twin / BallThread.java) of #2977.

Problem

While suspended, BallThread wakes every 250 ms only to re-check isSuspended and do nothing. Because resumeMe() 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

isSuspended is now guarded by a private lock. The run loop waits on that lock while suspended, and resumeMe() / stopMe() call notifyAll(). 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 first draw(), averaged over 5 runs:

resume latency
before 173 ms
after 1 ms

Notes

  • No test changes. BallThreadTest (suspend / resume / interrupt) passes unmodified, including the verifyNoMoreInteractions assertions and the RuntimeException-on-interrupt check.
  • notifyAll() in stopMe() is required: without it, stopping an already-suspended thread would block forever in wait().
  • twin/README.md embeds this class verbatim, so it is updated to match.
  • I did not claim a CPU reduction here. This loop sleeps rather than spinning, and measured CPU time was effectively zero both before and after. The real defect is responsiveness.
  • The other locations listed in Fix busy-waiting loops #2977 are untouched. The Retry classes use deliberate backoff sleeps rather than busy-waiting.

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

PR Summary

Refactored BallThread to replace the busy-wait loop with a wait/notify pattern guarded by a private lock. suspendMe() now sets isSuspended inside a synchronized block, resumeMe() and stopMe() call notifyAll() to wake the thread promptly. The 250ms animation pacing remains unchanged. Updated twin/README.md to document the change. No tests were modified; existing BallThread tests pass.

Changes

File Summary
twin/README.md Document updated to reflect BallThread's new wait/notify-based synchronization and lock usage; README now matches the code changes and behavior.
twin/src/main/java/com/iluwatar/twin/BallThread.java Replaces polling with a private lock and wait/notify. BallThread.run now waits while isSuspended is true, then draws/moves and sleeps 250 ms. suspendMe()/resumeMe()/stopMe() synchronize on the lock and notifyAll as needed, preserving the 250 ms pacing and improving responsiveness.

autogenerated by presubmit.ai

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ LGTM!

Review Summary

Commits Considered (2)
  • 7c10fec: docs: update twin README to match BallThread fix
  • 70d5788: fix: replace busy-wait in BallThread with wait/notify (#2977)
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

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.01%. Comparing base (4cabb20) to head (7c10fec).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
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.

1 participant