Issue
I have a large segment of code that is not a loop, just a list of commands that happens once but takes some time. I need it to either pause or terminate this at any point based on a changing boolean value. I could use a different thread to suspend, resume and stop this code, but those methods are deprecated, so I would like to avoid using them. I could check the boolean between every line of code, but I am hoping for a more elegant solution. Is there a good way to do this?
Solution
The correct way to handle interrupting a thread (in this case, to pause or stop it) is, naturally, with Thread#interrupt(). It is designed so that you can define safe points at which the thread can be interrupted, which for you is naturally the point between each task. So, to avoid having to manually check your variable between each task, and to be able to easily resume where you left off, you can store your tasks as a list of Runnables, and remember your position in the list from when you left off, like this:
public class Foo {
public static void runTask(Runnable task) throws InterruptedException {
task.run();
if (Thread.interrupted()) throw new InterruptedException();
}
Runnable[] frobnicateTasks = new Runnable[] {
() -> { System.out.println("task1"); },
() -> { Thread.currentThread().interrupt(); }, //Interrupt self only as example
() -> { System.out.println("task2"); }
};
public int frobnicate() {
return resumeFrobnicate(0);
}
public int resumeFrobnicate(int taskPos) {
try {
while (taskPos < frobnicateTasks.length)
runTask(frobnicateTasks[taskPos++]);
} catch (InterruptedException ex) {
}
if (taskPos == frobnicateTasks.length) {
return -1; //done
}
return taskPos;
}
public static void main(String[] args) {
Foo foo = new Foo();
int progress = foo.frobnicate();
while (progress != -1) {
System.out.println("Paused");
progress = foo.resumeFrobnicate(progress);
}
System.out.println("Done");
}
}
-->
task1
Paused
task2
Done
Answered By - Vitruvie
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.