Changes to JEP 453
Ron Pressler
ron.pressler at oracle.com
Sat May 20 00:31:36 UTC 2023
> On 19 May 2023, at 20:51, forax at univ-mlv.fr wrote:
>
> Okay, I think i understand the proposed change.
>
> The semantics for the JDK 19/20 has the invariant that after a call to join() the state of a Future was stable, i.e. it will never change later.
>
> Here you are breaking that invariant because a subtask with the state NOT_RUN will transition to either SUCCESS or FAILED depending how the subtask callable finished after the call to join().
NOT_RUN will never be run and will never change, but RUNNING will change to SUCCESS or FAILED.
>
> So I've the follow up questions:
> - do we agree that handleComplete() can only be called with a task in state SUCCESS or FAILED, never with a task in state RUNNING or NOT_RUN ?
That’s correct.
> - If a STS is used (but not a ShutdownOnXX), after a join(), a task state can return NOT_RUN. As a user how am i suppose to handle that case ? Do a busy loop to wait ?
I think you mean RUNNING rather than NOT_RUN, but anyway:
Structured concurrency is used when you want to treat subtasks that cooperate on a single task as a unit, not as individuals. After join you use the policy in a way that will let you know what the state of the subtasks is. For example, after throwIfFailed, all tasks have completed successfully. So if you’re even looking at what the state, you’re doing something wrong. You shouldn’t look at the state. If you’re not using a policy then you should be using a policy. If you’re an expert who knows what you're doing and choose to to ignore the recommendation of how the API should be used, then the RUNNING state after join means that the task has been cancelled, and it’s up to you what to do. In most situations you’ll probably want to ignore it; after all you shutdown the scope which means you’re not interested in the results of tasks that are still running (shutdown means: I have all the information I need to compute the scope’s result and I don’t care about the result of any further forks). If you’re doing something weird (I don’t even know what it would be) you could even call join again.
But really, as a user, you shouldn’t query the state so there’s no case to handle. As far as you’re concerned, the only method on Subtask is get. That’s why the JEP recommends to assign the Subtask to a Supplier and forget it’s anything other than that.
> - If a STS is used (but not a ShutdownOnXX), do you have considered to make join() synchronous to keep the invariant (stable state after join()) ?
I’m not sure what that means, but I don’t think a stable state matters. First, it shouldn’t ever be queried. Seriously, don’t. We allow it to offer maximal flexibility for experts, and we may not allow it if we see it confuses people. For another, it is monotonic; the only state that could change is RUNNING, and then it can only change to SUCCESS or FAILED. So if you’re an expert who chooses to ignore the recommended use of the API, this invariant is good enough.
— Ron
More information about the loom-dev
mailing list