3

I have read a lot of questions and answers in StackOverflow about interrupting Threads by throwing InterruptedException.

But most of the answers are using just a for loop and from time to time they check if the thread is interrupted with : Thread.currentThread().isInterrupted().

My code is like :

   public class UploadVideoRunnable implements Runnable {

       @Override 
       public void run() {
          isUploaded = new uploadMedia(title, uri);
        }
    }

How/Where should I add code to check if thread is interrupted?

Sorry if this is a noob question but I have searched google a lot and haven't found an answer.

Thanks

EDIT : updated code, uploadMedia is a class and not a method

beryllium
  • 29,669
  • 15
  • 106
  • 125
Mes
  • 1,671
  • 3
  • 20
  • 36
  • 2
    In `uploadMedia`. There's no magic to an interrupted check, it's just regular code: you can't check for interruption in the middle of code without putting a check in the middle of the code. – Andy Turner Sep 14 '16 at 13:49
  • 2
    Runnable != Thread – Blackbelt Sep 14 '16 at 13:51
  • @Blackbelt I used this answer [here](http://stackoverflow.com/a/9458785/4856442) and it recommends to pass a runnable and then call cancel. And I used this answer [here] to find out how to cancel the runnable. I understand what you are saying but I can't see how this affects my case. – Mes Sep 14 '16 at 14:08
  • Yes, but you don't interrupt a `Runnable` . The thing that you interrupt is a _thread_. The `Runnable` is just a wrapper for the code that you provide for the thread to execute. – Solomon Slow Sep 14 '16 at 14:32
  • @jameslarge Good point! Didn't notice that. Thanks for mentioning it James! – Mes Sep 14 '16 at 14:34
  • If that's really all there is to your `run()` method, and if `uploadMedia()` is not a method that you build from source code, then there's nothing you can do about it. Like @ghostcat says below, interruption only works if the code to be interrupted is interrupt-aware. – Solomon Slow Sep 14 '16 at 14:36

2 Answers2

2

"Interrupting" requires "cooperation" here.

This means: you can only interrupt calls ... that do contain such kind of loop construct:

while (notDone) { doSomething(); Thread.sleep(); }

or something alike. This means: you will have to look into that method uploadMedia() and see if that allows for such changes. So, you would change that to:

while (notDone) { 
  if(interrupted) {
    notDone = false;
   } else {
   doSomething(); 
   Thread.sleep(); 
   }
}

Of course, the above being more like "pseudo-code"; you have to fill out the details.

Alternatively, you can have a look into ExecutorServices; as there are some means to forcefully stop those; see here

EDIT: that shouldn't change a thing. You see - you are calling a method there; the constructor of that class. And for sure, that constructor will be calling other methods; and one of those other methods is the one that is running for a longer period of time to do its uploading work.

Finally: please note that interrupted could be also something like

if (externalThingy.hasBeenCancelled()) {

Meaning: you might have to add another parameter to your class; something that the Uploader class can query in some way to figure if it should stop doing what it is currently doing!

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • I understand what you mean and thanks a lot. I have edited answer, caused I did an error. `uploadMedia()` is a class and not a method. What does this change? – Mes Sep 14 '16 at 13:54
  • `that shouldn't change a thing` that's what I wanted to hear. Thanks for the answer. – Mes Sep 14 '16 at 13:57
  • I hope you got me right: you still have to dig into the source code of that class; to identify that spot that actually keeps that thread busy for a longer period of time. – GhostCat Sep 14 '16 at 13:58
  • I think so! I just have to pass an instance of the runnable into this class as a parameter and then identify the spot that's doing the heavy task and add a check for `isInterrupted()` ? Am I right ? – Mes Sep 14 '16 at 14:01
  • 1
    You dont have to pass down the runnable. You could try with checking if there is a Thread.sleep() somehwere ... that **ignores** its interrupted exceptions. If so, react to that exception instead. Let me know if that helps; I will come back later and check. – GhostCat Sep 14 '16 at 14:09
  • Updated my answer again; might help if "checking for interruptedexception" isnt good enough. – GhostCat Sep 14 '16 at 14:32
  • Inside uploadMedia() I have a method which uses a do-while() loop to uploads media in chunks. Just before `while()` I have added a `Thread.sleep(1000)` and I catch `InterrruptedException`. Inside the `catch` I'm running `Thread.currentThread().interrupt();` and I'm setting a variable to false. Every time do() runs I check the value of that variable. I have tried it 2-3 times and seems its working. What do you think? Should I use `Thread.sleep(1000)` a much smaller integer to sleep() than 1000 which I think causes the thread to stop for 1 second ? – Mes Sep 14 '16 at 14:39
1

In Android you can not interrupt / cancel thread of execution from outside (Bionic doesn't even implement pthread_cancel()). I.e. any thread must decide by itself if it should terminate (via returning from run()) or continue execution. The only way to notify some thread that it should terminate as soon as possible - to use interrupt() / isInterrupted() pair. Thread that should be terminated should periodically check if someone has interrupted it or not. So, you must split your job into small chunks and test between them. If you have no way to split it - you have nothing to do but only wait until that job will be finished.

Sergio
  • 8,099
  • 2
  • 26
  • 52
  • Do you have any documentation that tell me that returning from `run()` means it terminates the process? – Meik Vtune Sep 14 '16 at 14:52
  • @MeikVtune Returning from thread's `run()` doesn't terminate the whole process but only that thread. – Sergio Sep 14 '16 at 14:58
  • Sorry, that was what I was trying to say. – Meik Vtune Sep 14 '16 at 15:15
  • 1
    @MeikVtune I'm kind of surprised to see that the javadoc for `java.lang.Thread` does _not_ explicitly say that a thread dies when its `run()` method completes; but that's how it works. The closest that the `Thread` javadoc comes to saying so is where it talks about threads that _have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method._ – Solomon Slow Sep 14 '16 at 16:05