8

I am trying to terminate the thread in the following code:

public synchronized void run() {
    try {
        while (!Thread.currentThread().isInterrupted()) {
            this.scan();
            this.distribute();
            this.wait();
        }
    } catch (InterruptedException e) {}
}

public void cancel() {
    this.interrupt();
}

But the thread won't terminate. I used the debugger and found out that after the command this.interrupt(), the thread doesn't get interrupted (I put a watch on the expression this.isInterrupted() and it stays false). Anyone has an idea why this thread won't get interrupted?

Edit:

The problem has been found. Turns out that there were two instances of this thread. I am attaching the problematic code that lead to this:

/* (class Detector extends Thread) */
Detector detector = new Detector(board);
...
Thread tdetector  = new Thread(detector); /* WRONG!!! */
...
tdetector.start();
...
Community
  • 1
  • 1
Ori Popowski
  • 10,432
  • 15
  • 57
  • 79
  • what if you try it with `!Thread.interrupted()` in the condition – ratchet freak Dec 25 '11 at 01:19
  • There is no static method in class `Thread` by that name. And it would make no sense, because this is a method that is related to an instance of this class. – Ori Popowski Dec 25 '11 at 01:22
  • There certainly is a static method [`Thread.interrupted()`](http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#interrupted%28%29). I don't think it will help, though, because it basically does the same thing as the instance method (but also clears the interrupted flag, which might complicate things). – Ted Hopp Dec 25 '11 at 01:30
  • I misread it as `!Thread.interrupt()`. Anyway, I don't have any idea why it's happening and I am really frustrated. – Ori Popowski Dec 25 '11 at 01:33
  • I tried calling `interrupt()` directly from the thread which supposed to terminate this thread and it also doesn't work. – Ori Popowski Dec 25 '11 at 01:35
  • do not `synchronize(thread)`, you may face a lot of issues. – bestsss Dec 25 '11 at 02:11

2 Answers2

5

According to the docs, if you call interrupt() while the thread is in a wait() state, the interrupt flag will not be set. You should be getting an interrupted exception, which will exit the loop (and the thread).

EDIT

Per my comment and your response, the problem is that you have more than one of these threads running.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • But the thread doesn't terminate. The whole program doesn't terminate because of this thread. – Ori Popowski Dec 25 '11 at 01:06
  • 1
    @LeifEricson - Is the thread stuck in some compute cycle inside `scan()` or `distribute()`? – Ted Hopp Dec 25 '11 at 01:10
  • No. I used the debugger to confirm that it never gets stuck inside these methods. – Ori Popowski Dec 25 '11 at 01:12
  • The main issue here, is that the interrupted flag doesn't get set. It is both bizarre and annoying. – Ori Popowski Dec 25 '11 at 01:15
  • This is a bit of a stumper. Try changing `Thread.currentThread().isInterrupted()` to just `isInterrupted()` (or `this.isInterrupted()` if you prefer). It shouldn't make a difference, but who knows... – Ted Hopp Dec 25 '11 at 01:27
  • 1
    @LeifEricson - Might it be that you have more than one instance of this Thread object? – Ted Hopp Dec 25 '11 at 01:44
  • I've tried `this.interrupted()` before I posted this question. BTW, putting the expression `this.isInterrupted() == Thread.currentThread.isInterrupted` to watch in the debugger yielded `false`. As for your second comment - I will check. – Ori Popowski Dec 25 '11 at 01:49
  • You were right about having two threads. A tragic and embarassing mistake. I'll post the problematic code as an edit to my question. Thank you very much. – Ori Popowski Dec 25 '11 at 01:53
  • 1
    @LeifEricson - `this.isInterrupted() == Thread.currentThread.isInterrupted` is probably not being evaluated in the thread represented by `this`. – Ted Hopp Dec 25 '11 at 01:57
  • If you would have written your idea about having two thread as an answer I would accept it. But the system doesn't let me write [SOLVED] in the question title. So go ahead and write it, so I can accept it and the thread will be closed. – Ori Popowski Dec 25 '11 at 16:32
  • @LeifEricson - Answer updated. You mark the question as solved by clicking on the outline of the check mark next to the answer that solves the problem. Cheers. – Ted Hopp Dec 25 '11 at 16:36
2

You are probably calling cancel on the wrong thread. If you look at it, it cancel() cancels this thread. You probably want to cancel some other thread.

It is also true that your call to isInterrupted() is unnecessary, but that won't cause interrupts to be lost ...


On the other hand, if the cancel method is a method of a class that extends Thread, then the this could be the thread that needs cancelling. (The problem for us folks trying to answer is that there is/was insufficient detail in the original question ...)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • `cancel` appears to be an instance method, so `interrupt` is being called on the correct Thread object. The method certainly does not have to be called while executing on that thread (which would render the method kind of useless). The call to `isInterrupted()` is necessary if the call to `interrupt()` occurs while the thread is actually computing (in which case no InterruptedException is thrown). – Ted Hopp Dec 25 '11 at 01:09
  • 1
    No. I want to terminate this thread. Another thread calls the `cancel` method. This is the only way I know for terminating a thread which has blocking methods (like `wait()`) – Ori Popowski Dec 25 '11 at 01:11
  • But when `Another` thread calls cancel it is canceling itself, not you. You need to find a way of storing **your** thread to cancel. Probably in your `run` method, store your `Thread.getCurrentThread()` and then in your `cancel` interrupt **that** thread. – OldCurmudgeon Dec 25 '11 at 01:48