Fix the loop that starts threads and exits
This code is meant to start ten threads that each print a number, then let them finish. It does not even compile, and one more defect would stop the output even after a compile fix. Find both and correct them.
Constraints:
- keep ten threads, each printing its own index
- the program must actually wait for the threads' output
for (int i = 0; i < 10; i++) {
Thread t = new Thread(() -> {
try { Thread.sleep(200); } catch (InterruptedException ignored) {}
System.out.println(i);
});
t.start();
}
System.exit(0);
Find and fix the bugs.
Two bugs. First, the lambda captures i, but a loop variable is not effectively final, so it does not compile — copy it into a final local (final int n = i;) and print n. Second, System.exit(0) terminates the JVM immediately, killing the sleeping threads before they print — remove it (or join each thread first) so the program waits for their output.
- ✗Thinking a
forloop variable is effectively final and can be captured directly - ✗Overlooking that
System.exit(0)kills the JVM and the still-running threads - ✗Confusing the fix with adding
volatile, which addresses visibility, not capture or exit
- →Why is a
forloop variable not effectively final while a foreach variable can be? - →How would
joinon each thread change the program's behavior versus removingSystem.exit?
Fix
for (int i = 0; i < 10; i++) {
final int n = i; // a copy — effectively final for the lambda
Thread t = new Thread(() -> {
try { Thread.sleep(200); } catch (InterruptedException ignored) {}
System.out.println(n);
});
t.start();
}
// System.exit(0); ← removed: it killed the sleeping threads before any output
Bug 1 — capturing the loop variable. A lambda may only capture effectively final variables. i changes every iteration, so it is not effectively final and the code does not compile. The fix is to copy the value into a fresh local final int n = i; and use n inside the lambda.
Bug 2 — System.exit(0). Even after the compile fix, System.exit(0) terminates the JVM immediately. The threads sleep 200 ms and never get to print. Remove the call — the JVM then stays alive while the started non-daemon threads run. If you need a deterministic finish, call t.join() on each thread before main ends.