【问题标题】:precise behaviour of interrupt() method with respective to thread states in java与java中线程状态相关的interrupt()方法的精确行为
【发布时间】:2016-10-27 20:04:30
【问题描述】:

我已经阅读了下面的帖子

What does java.lang.Thread.interrupt() do? 但我没能完全正确

我引用@Mike_q 对上述问题的回答如下

Thread.interrupt() 设置目标线程的中断状态/标志。然后在该目标线程中运行的代码可以轮询中断状态并适当地处理它。一些阻塞的方法如 Object.wait() 可能会立即消耗中断状态并抛出适当的异常(通常是 InterruptedException)

它说当对象处于 WAITING 时它可以消耗中断状态,那么当它处于 BLOCKED 状态等待对象的锁定时会发生什么......?

我已经在下面尝试了这种情况,代码是

在 X:t2 被阻止

    public class interruptsyc
{
    static Object resource = new Object();
    public static void main(String []args)
    {
        System.out.println("started main");
        Thread1 t1=new Thread1("thread 1");
        t1.start();
        delay(1000);
        Thread2 t2 =new Thread2("thread 2");
        t2.start();
        delay(1000);
        t2.interrupt(); // X: at this point t2 is in blocked state waiting for resource's lock
        System.out.println(t2.getName()+t2.interrupted());
        delay(1000);
        System.out.println("end main");

    }
    static void delay(long n)
    {
        try
        {
        Thread.sleep(n);
        }
        catch(InterruptedException ex)
        {
            System.out.println(Thread.currentThread().getName()+Thread.interrupted());
            ex.printStackTrace();
        }
    }
    static class Thread1 extends Thread{

        Thread1(String name)
        {
            setName(name);
        }
        public void run()
        {
            synchronized(resource)
            {
                System.out.println("start 1");
                delay(6000);
                System.out.println("end 1");
            }
        }
    }
    static class Thread2 extends Thread{
        Thread2(String name )
        {
        setName(name);  
        }
        public void run()
        {
            synchronized(resource)
            {
                System.out.println("start 2");
                delay(2000);
                System.out.println("end 2");
            }
        }
    }
}

输出低于

started main
start 1
false
end main
end 1
start 2
thread 2false
java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method)
        at interruptsyc.delay(interruptsyc.java:25)
        at interruptsyc$Thread2.run(interruptsyc.java:59)
end 2

好像调用了InterruptedException,后面调用sleep方法的时候……这是为什么……?

再一次,我从这里所说的内容中不太明白什么是轮询

通过 Thread.interrupted() 方法进行轮询,该方法返回当前线程的中断状态并清除该中断标志。通常线程可能会做一些事情,比如抛出 InterruptedException。

每当我在上面的代码中调用 Thread2.interrupted() 方法时,它都会返回 false (当我在 t2.interrupt 之后和 catch 块中调用时)

【问题讨论】:

    标签: java multithreading interrupt thread-sleep interrupted-exception


    【解决方案1】:

    好像调用了InterruptedException,后面调用sleep方法的时候……这是为什么……?

    因为阻塞/休眠方法不会立即阻塞。他们首先检查线程是否被中断,如果已经被中断,则立即抛出 InterruptedException,以便线程尽快停止。

    每当我在上面的代码中调用 Thread2.interrupted() 方法时,它都会返回 false

    因为当阻塞/休眠方法抛出 InterruptedException 时,它们也会清除中断标志。

    这是在Thread.sleep()的javadoc中:

    抛出 InterruptedException - 如果任何线程中断了当前线程。抛出该异常时清除当前线程的中断状态。

    【讨论】:

    • 但是上面代码中的t2.interrupt()此时还没有抛出中断异常并且中断标志仍然有效
    • 不知道你在问什么,但我认为你对t2.interrupted() 的电话引起了一些混乱。 ìinterrupted() 是一个静态 方法。它检查当前线程是否被中断。所以你不应该把它叫做t2.interrupted(),而应该叫做Thread.interrupted()。要知道在另一个线程被中断,无需清除中断标志,使用t2.isInterrupted()。我重写了您的代码以产生更有意义的输出:gist.github.com/jnizet/1e983582a5f5d8b1e9b6a81ed2a731e9
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多