Reputation: 51
Similar to this question, but with difference is in the details: Interrupting a thread that waits on a blocking action?
There is a 3pty library that I don't control, this library has a method pressButtonAndHoldIt(long duration)
. This is a blocking method, meaning that if you set duration
to 10 minutes - it will be doing something for 10 minutes (without interruptions).
I use this method from a separate thread, so I can do something else while "holding the button":
final Future<?> f = Executors.newSingleThreadExecutor().submit(() -> {
3ptyLibrary.pressButtonAndHoldIt(Duration.ofMinutes(10).toSeconds());
});
var stuff = myOtherStuff();
//here I want to stop what was submitted in "f", e.g. "f.forceStop()"
Usually myOtherStuff()
takes about 9 minutes, but sometimes it could take 5 minutes, so I want to stop that blocking background process. How can I do that?
Note that Executors.newSingleThreadExecutor().submit()
is just an example: I am able to create a background thread in any way we can in java (if that helps).
Upvotes: 0
Views: 45
Reputation: 103913
The one and only thing you can do, is call thatThreadRef.interrupt();
and pray.
What interrupt() does is 'raise the interrupt flag'. This accomplishes only two things:
InterruptedException
, such as Thread.sleep
. Those methods will IMMEDIATELY return (by throwing InterruptedException) if the flag is up when you call them, never sleeping at all. If you interrupt the thread while they are sleeping, they will exit near immediately by throwing that too.Now, that second thing is not quite completely useless: A method is free to check it from time to time and act accordingly, doing whatever seems appropriate (there isn't much of an actual semantic standard as to what you ought to do. As long as you return or otherwise break off something). For example, on most OSes, but not all of them, reading a file (which is not specced to throw InterruptedException
) can block, and if you interrupt that, generally that does actually work and aborts the read, causing an IOException
to occur. The point is, the JVM doesn't guarantee it (hey, if you have to run on a combinatorial explosion of architectures and OSes, you gotta go light on the guarantees).
So, that's your plan: Pray that this pressButtonAndHoldIt thing looks at it.
If it doesn't, there's virtually nothing you can do directly. Your best bet at that point, if truly the library doesn't support it (not via interrupt and not in any other way) and you can't edit the source or contribute a pull request with an update, is to start an entirely new JVM from your JVM (not easy), and then hard-kill that in order to try to 'abort' that blocking operation. That, itself, may not work (in which case, that's a pretty bad library, if it leaks a resource if its VM dies). That is quite a big gun to kill this particular mosquito, but it's the only one you have.
Upvotes: 3