简体   繁体   中英

How can i understand Thread.interrupt()?

There are two code block in java.

Block One:

@Test
public void test1() {

    System.out.println("interrupt:" + Thread.currentThread().isInterrupted());
    Thread.currentThread().interrupt();
    System.out.println("interrupt:" + Thread.currentThread().isInterrupted());

}

Output:

interrupt:false
interrupt:true

Block Two:

@Test
public void test2() throws InterruptedException {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("running...");
        }
    });

    thread.interrupt();

    TimeUnit.SECONDS.sleep(2);

    System.out.println("interrupt:" + thread.isInterrupted());

    thread.start();

    TimeUnit.SECONDS.sleep(2);

    System.out.println("interrupt:" + thread.isInterrupted());

}

Output:

interrupt:false
running...
interrupt:false

So, my questions:

  1. Why block one print interrupt:true after invoke interrupt() but block two not?
  2. What will JVM do after invoke interrupt()?

Thanks!

PS:Block Three:

@Test
public void test3() {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("running...");
        }
    });

    thread.interrupt();

    System.out.println("interrupt:" + thread.isInterrupted());

    // thread.start();
    //
    // thread.interrupt();
    //
    //
    // System.out.println("interrupt:" + thread.isInterrupted());

}

Also output : interrupt:false

  • In block 1, you interrupt yourself, this "flag" the thread with interrupted flag.
  • In block 2, you interrupt other thread (that is not alive -not started-)

try in the run() method add Thread.sleep(5000); and start before interrupt ;-)

How interrupt works

It's quite easy. Due to the sleep documentation:

InterruptedException - if another thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

When you called interrupt and the thread was sleeping the exception was thrown and it simply cleared the interrupted flag.

Block three:

Due to the documentation: Interrupting a thread that is not alive need not have any effect. So to sum up: if your thread hasn't started yet interrupt method may not work.

In the source code of java.lang.Thread , for the interrupt method the documentation clearly says:

Interrupting a thread that is not alive need not have any effect.

  888       /**
  889        * Interrupts this thread.
  890        *
  891        * <p> Unless the current thread is interrupting itself, which is
  892        * always permitted, the {@link #checkAccess() checkAccess} method
  893        * of this thread is invoked, which may cause a {@link
  894        * SecurityException} to be thrown.
  895        *
  896        * <p> If this thread is blocked in an invocation of the {@link
  897        * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
  898        * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
  899        * class, or of the {@link #join()}, {@link #join(long)}, {@link
  900        * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
  901        * methods of this class, then its interrupt status will be cleared and it
  902        * will receive an {@link InterruptedException}.
  903        *
  904        * <p> If this thread is blocked in an I/O operation upon an {@link
  905        * java.nio.channels.InterruptibleChannel </code>interruptible
  906        * channel<code>} then the channel will be closed, the thread's interrupt
  907        * status will be set, and the thread will receive a {@link
  908        * java.nio.channels.ClosedByInterruptException}.
  909        *
  910        * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
  911        * then the thread's interrupt status will be set and it will return
  912        * immediately from the selection operation, possibly with a non-zero
  913        * value, just as if the selector's {@link
  914        * java.nio.channels.Selector#wakeup wakeup} method were invoked.
  915        *
  916        * <p> If none of the previous conditions hold then this thread's interrupt
  917        * status will be set. </p>
  918        *
  919        * <p> Interrupting a thread that is not alive need not have any effect.
  920        *
  921        * @throws  SecurityException
  922        *          if the current thread cannot modify this thread
  923        *
  924        * @revised 6.0
  925        * @spec JSR-51
  926        */
  927       public void interrupt() {
  928           if (this != Thread.currentThread())
  929               checkAccess();
  930   
  931           synchronized (blockerLock) {
  932               Interruptible b = blocker;
  933               if (b != null) {
  934                   interrupt0();           // Just to set the interrupt flag
  935                   b.interrupt(this);
  936                   return;
  937               }
  938           }
  939           interrupt0();
  940       }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM