diff --git a/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java b/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java index 5440f2e747f..f4e624c5852 100644 --- a/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java +++ b/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java @@ -576,8 +576,6 @@ public class StructuredTaskScope implements AutoCloseable { } SubtaskImpl subtask = new SubtaskImpl<>(this, task, round); - boolean started = false; - if (s < SHUTDOWN) { // create thread to run task Thread thread = factory.newThread(subtask); @@ -588,15 +586,14 @@ public class StructuredTaskScope implements AutoCloseable { // attempt to start the thread try { flock.start(thread); - started = true; } catch (IllegalStateException e) { // shutdown by another thread, or underlying flock is shutdown due // to unstructured use } } - // force owner to join if thread started - if (started && Thread.currentThread() == flock.owner() && round > forkRound) { + // force owner to join if this is the first fork in the round + if (Thread.currentThread() == flock.owner() && round > forkRound) { forkRound = round; } @@ -939,7 +936,8 @@ public class StructuredTaskScope implements AutoCloseable { T r = (T) result; return r; } - throw new IllegalStateException("Subtask not completed or did not complete successfully"); + throw new IllegalStateException( + "Result is unavailable or subtask did not complete successfully"); } @Override @@ -949,7 +947,8 @@ public class StructuredTaskScope implements AutoCloseable { if (result instanceof AltResult alt && alt.state() == State.FAILED) { return alt.exception(); } - throw new IllegalStateException("Subtask not completed or did not complete with exception"); + throw new IllegalStateException( + "Exception is unavailable or subtask did not complete with exception"); } @Override diff --git a/test/jdk/java/util/concurrent/StructuredTaskScope/StructuredTaskScopeTest.java b/test/jdk/java/util/concurrent/StructuredTaskScope/StructuredTaskScopeTest.java index 11e3f70b3ed..5ed7af8c46b 100644 --- a/test/jdk/java/util/concurrent/StructuredTaskScope/StructuredTaskScopeTest.java +++ b/test/jdk/java/util/concurrent/StructuredTaskScope/StructuredTaskScopeTest.java @@ -279,6 +279,7 @@ class StructuredTaskScopeTest { executed.set(true); return null; }); + scope.join(); assertEquals(Subtask.State.UNAVAILABLE, subtask.state()); assertThrows(IllegalStateException.class, subtask::get); assertThrows(IllegalStateException.class, subtask::exception); @@ -673,22 +674,6 @@ class StructuredTaskScopeTest { } } - /** - * Test that shutdown prevents new threads from starting. - */ - @Test - void testShutdownWithFork() throws Exception { - ThreadFactory factory = task -> null; - try (var scope = new StructuredTaskScope(null, factory)) { - scope.shutdown(); - // should not invoke the ThreadFactory to create thread - Subtask subtask = scope.fork(() -> null); - assertEquals(Subtask.State.UNAVAILABLE, subtask.state()); - assertThrows(IllegalStateException.class, subtask::get); - assertThrows(IllegalStateException.class, subtask::exception); - } - } - /** * Test that shutdown interrupts unfinished subtasks. */ @@ -1377,6 +1362,7 @@ class StructuredTaskScopeTest { // fork after shutdown Subtask subtask = scope.fork(task); + scope.join(); assertEquals(task, subtask.task()); assertEquals(Subtask.State.UNAVAILABLE, subtask.state()); assertThrows(IllegalStateException.class, subtask::get);