This is probably a question with many possible answers, but I'm asking for the best design, rather than "how can this be done at all".

Let's assume we are implementing a program with a UI that computes Pi. I can hit a "Start" button to start the computation and a "Stop" button to abort the computation, giving me a message box with the highest precision value of Pi computed so far.

I guess the straight forward approach would be starting a Runnable in a new Thread. The runnable computes Pi, and stores the current value in a shared variable, both threads have access to. "Stop" would abort the Thread, and display the shared variable.

I have a feeling this could be implemented more elegantly, though, but I'm not sure how. Maybe using a CompletableFuture?

I'd rather solve this without adding any new libraries to my project, but if you know a library that supports this particularly well, please leave it in the comments.

Obviously, computing Pi will never finish. It would be great though, if the solution also supports e.g. computing the best move in a game of chess. Which will finish, given enough time, but usually has to be aborted, returning the best move so far.