0

I try to consider with multithreading and with interrupt() method:

    public static void main(String[] args) throws InterruptedException {
        System.out.println(Thread.currentThread().isInterrupted());
        Runnable target = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("From thread-run(): " + Thread.currentThread().isInterrupted());
                    Thread.sleep(7000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("From thread-catch(): " + Thread.currentThread().isInterrupted());
                }
            }
        };
        Thread someThread = new Thread(target);
        System.out.println("Before start(): " + someThread.isInterrupted());
        someThread.start();
        Thread.sleep(1000);
        System.out.println("After start(): " + someThread.isInterrupted());
        someThread.interrupt();
        Thread.sleep(1000);
        System.out.println("After interrupt: " + someThread.isInterrupted());
    }

As I understood, the interrupt() method set flag interrupt to true. In this case, the thread supposed to be stopped immediately, but my code return false in all cases:

enter image description here

I changed my method in the way when the thread interrupt himself:

    public static void main(String[] args) throws InterruptedException {
        System.out.println(Thread.currentThread().isInterrupted());
        Runnable target = new Runnable() {
            @Override
            public void run() {
                    System.out.println("From thread-run(): " + Thread.currentThread().isInterrupted());
                    Thread.currentThread().interrupt();
            }
        };
        Thread someThread = new Thread(target);
        System.out.println("Before start(): " + someThread.isInterrupted());
        someThread.start();
        Thread.sleep(1000);
        System.out.println("After start(): " + someThread.isInterrupted());
        Thread.sleep(1000);
        System.out.println("After interrupt: " + someThread.isInterrupted());
    }

But the result is the same:

enter image description here

I supposed, the From thread-catch(): and After interrupt: lines should have returned true instead of false - why isInterrupted() == false if the thread was interrupted?


the answer from Why do InterruptedExceptions clear a thread's interrupted status? do not acceptable for my case since in the second case the InterruptException do not happen and

  • a) not "would have to explicitly clear that flag":
  • b) I used Thread.currentThread().interrupt() - anyway I got false
  • c) The interrupt() was handled once

enter image description here

Valentyn Hruzytskyi
  • 1,772
  • 5
  • 27
  • 59
  • 1
    Please do not repost [your questions](https://stackoverflow.com/questions/69290119/isinterrupted-return-false-after-interrupt-how-the-interrupt-work). If you do not believe the duplicate links apply, edit the existing question to explain why. – Sotirios Delimanolis Sep 22 '21 at 19:53
  • @SotiriosDelimanolis exactly that I did in the last part of the my question, please review it – Valentyn Hruzytskyi Sep 22 '21 at 20:02
  • You should have done that in the original. There are multiple duplicates. The first link addresses your first case. The second and third address the question you added later (which you shouldn't be doing either in the main post either, ask a new one). – Sotirios Delimanolis Sep 22 '21 at 20:03
  • @SotiriosDelimanolis, sorry, but the first question was closed as duplicate and I was forced to delete him....should I create a new question, since this is also closed? – Valentyn Hruzytskyi Sep 22 '21 at 20:10
  • 1
    @ValentynHruzytskyi Who/what "forced" you to delete it? You should create new questions to ask new questions. Both your questions have been answered (by the duplicates linked and more across the site) so I don't see why you would. – Sotirios Delimanolis Sep 22 '21 at 20:18
  • The spec of Thread.isInterrupted() explicitly says: Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method. Returns: true if this thread has been interrupted; false otherwise. So the behavior you see is the correct one. – Sergey Tsypanov Sep 23 '21 at 14:27

2 Answers2

1

The spec works precisely as it says it does. When InterruptedException is thrown, the flag is also lowered as it does that. Programming goes by spec. It doesn't really care that you find an answer 'unacceptable'.

The second case gives you a false because the thread is already dead. You interrupt your own thread, which does absolutely nothing except raise that flag. That raised flag will then have an effect only on methods that are explicitly marked as looking at it, such as Thread.sleep (the next Thread.sleep you would execute in that thread will end immediately, waiting no time at all, and end by throwing InterruptedException (which will, of course, also lower the flag).

At any rate, okay, so, the flag is up, you then call no methods that look at it, and the thread ends because it ran to the end of the run() method. At which point, things like 'interrupted' status are irrelevant, and no longer tracked.

If you're calling isInterrupted(), you're probably doing it wrong, but this question does not indicate why you (think you) need this, so it is not possible to name some good alternatives.

At any rate, if you interrupt a thread, then isInterrupted() will return true until [A] that thread lowers the flag by calling Thread.interrupted(), [B] same as A but be aware that other methods and notably a bunch of methods in java.* do this for you. Notably, Thread.sleep; after a sleep() call exits, the interrupt flag cannot possibly be raised anymore. If it was raised at any time before or during the sleep, the sleep method lowers it and exits by way of throwing InterruptedException. It does this. By design. You can't make it no do this, or [C] the thread ends entirely.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
1

Take a look at the javadoc of someThread.isInterrupted() method: 'A thread interruption ignored because a thread was not alive at the time of the interrupt will be reflected by this method returning false.' - I think it is the reason.

Also you should know, that you must listen for 'interrupted status' on yourself. By checking Thread.currentThread().isInterrupted(). And then may be throw new InterruptedException() on yourself.

Try the code below. The loop logic just for 'waiting' - you cannot use Thread.sleep(10_000) after thread interrupted.


    public static void main(String[] args) throws InterruptedException {
        System.out.println(Thread.currentThread().isInterrupted());
        Runnable target = new Runnable() {
            @Override
            public void run() {
                System.out.println("From thread-run(): " + Thread.currentThread().isInterrupted());
                Thread.currentThread().interrupt();
                System.out.println("After interruption");
                long sum = 0;
                Random r = new Random();
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                    sum += r.nextInt(3);
                }
                System.out.println(sum);
                try {
                    Thread.sleep(10_000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("InterruptedException");
                }
            }
        };
        Thread someThread = new Thread(target);
        System.out.println("Before start(): " + someThread.isInterrupted());
        someThread.start();
        Thread.sleep(1000);
        System.out.println("After start(): " + someThread.isInterrupted());
    }

Outputs:

false
Before start(): false
From thread-run(): false
After interruption
After start(): true
2147470801
java.lang.InterruptedException: sleep interrupted
    at java.base/java.lang.Thread.sleep(Native Method)
    at ru.eta2.Test$1.run(Test.java:20)
    at java.base/java.lang.Thread.run(Thread.java:834)
InterruptedException

Process finished with exit code 0
Timur Efimov
  • 358
  • 2
  • 10