javastructured-concurrencyjava-22structured-task-scope

Is this a Java bug or am I misusing Java (preview)'s structured task scope?


So I have this code excerpt (a minimal reproduction, from a much larger project, and blocking issue). It leverages Java 22 (preview)'s structured task scope in combo with virtual threads:

playground.java

void main() throws InterruptedException {
  final var NAME = ScopedValue.<String>newInstance();
  try (var ts = new StructuredTaskScope<>()) {
    ScopedValue.runWhere(NAME, "haha", () -> {
      ts.fork(() -> {
   // ^^^
   // java.util.concurrent.StructureViolationException: Scoped value bindings have changed
        return null;
      });
    });
    ts.join();
  }
}

Using Java 22, you can run it with java --enable-preview --source 22 playground.java.


Solution

  • You are using the structured task scope wrong.

    The JavaDoc for StructuredTaskScope.fork() states:

    StructureViolationExceptionPREVIEW - if the current scoped value bindings are not the same as when the task scope was created

    Your code changes the scoped value bindings by calling ScopedValue.runWhere(NAME, "haha", () -> {}); after the task scope was created.

    You should probably structure your code like this:

    void main() throws InterruptedException {
      final var NAME = ScopedValue.<String>newInstance();
      ScopedValue.runWhere(NAME, "haha", () -> {
        try (var ts = new StructuredTaskScope<>()) {
          ts.fork(() -> {
            return null;
          });
        });
        ts.join();
      }
    }
    

    Or you can create a new task scope after changing the scoped value:

    void main() throws InterruptedException {
      final var NAME = ScopedValue.<String>newInstance();
      try (var ts = new StructuredTaskScope<>()) {
        ScopedValue.runWhere(NAME, "haha", () -> {
          try (var ts2 = new StructuredTaskScope<>()) {
            ts2.fork(() -> {
              return null;
            });
            ts2.join();
          }
        });
        ts.join();
      }
    }