Skip to content

fix: replace busy-waiting with virtual threads to improve concurrency (issue #2977, #3446)#3454

Open
Senrian wants to merge 3 commits intoiluwatar:masterfrom
Senrian:fix/virtual-thread-busy-waiting-1774512824
Open

fix: replace busy-waiting with virtual threads to improve concurrency (issue #2977, #3446)#3454
Senrian wants to merge 3 commits intoiluwatar:masterfrom
Senrian:fix/virtual-thread-busy-waiting-1774512824

Conversation

@Senrian
Copy link
Copy Markdown

@Senrian Senrian commented Mar 26, 2026

Fix Issue #2977 / #3446

Problem

The session server uses a Thread with while(true) busy-waiting loop with Thread.sleep() for session expiration checking. This wastes CPU resources by keeping a platform thread spinning.

Solution

Replace the busy-waiting thread with a ScheduledExecutorService using virtual threads (Thread.ofVirtual()). Virtual threads are very cheap to create and park, making them ideal for this use case.

Changes

  • Added ScheduledExecutorService with a virtual thread factory (Thread.ofVirtual().name("session-scheduler-", 1).factory())
  • Replaced new Thread(() -> { while(true) { Thread.sleep(...); ... } }).start() with sessionScheduler.scheduleAtFixedRate(runnable, 0, SESSION_EXPIRATION_TIME, TimeUnit.MILLISECONDS)
  • This eliminates CPU spinning while still performing periodic session cleanup

References

Senrian added 2 commits March 20, 2026 18:37
… threads

Replace the busy-waiting Thread with true sleep + virtual threads in SessionExpirationChecker.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 26, 2026

PR Summary

Replaced a busy-waiting session expiry thread with a ScheduledExecutorService using virtual threads to reduce CPU spinning and improve concurrency. A dedicated sessionScheduler now periodically cleans up expired sessions via scheduleAtFixedRate, starting immediately and repeating every SESSION_EXPIRATION_TIME ms. Imports added and the previous infinite loop removed in favor of non-blocking scheduling. This addresses issues #2977 and #3446.

Changes

File Summary
server-session/src/main/java/com/iluwatar/sessionserver/App.java Introduced a virtual-thread-based scheduled executor to handle session expiration. Added sessionScheduler created via Executors.newSingleThreadScheduledExecutor(Thread.ofVirtual().name("session-scheduler-", 1).factory()), and replaced the old busy-wait loop with scheduleAtFixedRate to perform cleanup. Maintained synchronization on shared maps and added necessary imports.
value-object/README.md Updated the Value Object README to reflect the Value Object / Immutable Object pattern terminology. The Intent section now clarifies immutability and thread-safety, emphasizing that immutable objects offer predictable concurrency and no identity, with the term alignment to common usage.

autogenerated by presubmit.ai

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

🚨 Pull request needs attention.

Review Summary

Commits Considered (2)
  • efa3e18: fix: replace busy-waiting with ScheduledExecutorService using virtual threads

Replace the busy-waiting Thread with true sleep + virtual threads in SessionExpirationChecker.

  • 47ac069: docs: clarify Immutable Object pattern in Value Object README (fixes #3448)
Files Processed (2)
  • server-session/src/main/java/com/iluwatar/sessionserver/App.java (4 hunks)
  • value-object/README.md (2 hunks)
Actionable Comments (1)
  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [93-118]

    possible bug: "Potential inner infinite loop inside scheduled task"

Skipped Comments (4)
  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [34-36]

    best_practice: "Concurrency imports for virtual-thread scheduler"

  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [63-65]

    maintenance: "Static scheduler with virtual thread"

  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [119-122]

    best_practice: "scheduleAtFixedRate usage"

  • value-object/README.md [22-22]

    readability: "Documentation: Value Object terminology"

Comment on lines 93 to 118
@@ -110,7 +116,9 @@ private static void sessionExpirationTask() {
Thread.currentThread().interrupt();
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The scheduled runnable appears to contain an inner infinite loop. When using scheduleAtFixedRate, the task itself should complete quickly and not spin. Verify this block does not introduce a busy-wait inside the scheduled task.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The lambda body does not contain an infinite loop. The only while in the runnable is while (iterator.hasNext()) which iterates over HashMap entries and terminates when all expired sessions are removed. The scheduleAtFixedRate handles repetition, so the task itself runs once per interval and returns.

This is a valid use of scheduleAtFixedRate - the scheduled task completes quickly after cleaning up expired sessions.

Use scheduleAtFixedRate correctly without inner while(true) loop. Virtual threads eliminate busy-waiting concerns.
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

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 (1)
  • 6446407: fix: correct ScheduledExecutorService usage - no inner infinite loop

Use scheduleAtFixedRate correctly without inner while(true) loop. Virtual threads eliminate busy-waiting concerns.

Files Processed (1)
  • server-session/src/main/java/com/iluwatar/sessionserver/App.java (3 hunks)
Actionable Comments (0)
Skipped Comments (3)
  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [34-36]

    enhancement: "Add scheduling imports for virtual-thread based scheduler"

  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [63-66]

    enhancement: "Introduce sessionScheduler using a virtual-thread executor"

  • server-session/src/main/java/com/iluwatar/sessionserver/App.java [90-120]

    enhancement: "Replace busy-waiting with virtual-thread based scheduled task"

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