Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我需要同步对中断方法的调用吗?_Java_Multithreading_Interrupt - Fatal编程技术网

Java 我需要同步对中断方法的调用吗?

Java 我需要同步对中断方法的调用吗?,java,multithreading,interrupt,Java,Multithreading,Interrupt,查阅JavaDocs和JavaSE7中Thread.interrupt()方法的源代码,我发现: public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interr

查阅JavaDocs和
JavaSE7
Thread.interrupt()
方法的源代码,我发现:

public void interrupt() {
    if (this != Thread.currentThread())
        checkAccess();

    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
            interrupt0();           // Just to set the interrupt flag
            b.interrupt(this);
            return;
        }
    }
    interrupt0(); //1, Outside of the synchronized block
}

//...

private native void interrupt0();
可以看出,
//1
处的本机方法调用在同步块之外。那么,如果不将对
interrupt()
方法的调用放入
synchronized
块,安全吗

Thread t;
//something else
t.interrupt(); //Not in a synchronized block

它是线程安全的吗?如果同时有多个线程试图中断它,该怎么办?那么本机方法interrupt0将如何运行呢?

是的,消息来源说中断死线程没有任何效果。所以它本质上是线程安全的

它说“中断一个不活动的线程不需要有任何效果。”

中断此线程。除非当前线程正在中断 它本身(始终是允许的)的checkAccess()方法 线程被调用,这可能导致抛出SecurityException。 如果该线程在wait()的调用中被阻塞,wait(long), 或对象类或join()的wait(long,int)方法, join(long)、join(long,int)、sleep(long)或sleep(long,int)方法 则其中断状态将被清除,并且 接收中断异常。如果此线程在I/O中被阻塞 对java.nio.channels.interruptbleChannel的操作 中断通道然后通道将关闭,线程的 中断状态将被设置,线程将收到 java.nio.channels.ClosedByInterruptException。如果这个线程是 在java.nio.channels.Selector中阻塞,然后线程的中断 将设置状态,并立即从选择返回 操作,可能使用非零值,就像选择器 调用了java.nio.channels.Selector唤醒方法。如果没有 如果先前的条件保持不变,则此线程的中断状态将为 设置中断一个非活动线程不需要有任何效果


我会说是的。。。它是线程安全的

原因:

  • 如果应用程序需要在
    synchronized
    块中调用
    interrupt()
    ,那么规范(javadoc)会这样说,并说明需要在哪个对象上进行同步以实现线程安全。事实上,javadoc对此只字未提

  • 如果应用程序需要在
    synchronized
    块中调用
    interrupt()。没有

  • 如果
    线程
    对象上的外部同步是使
    中断()调用线程安全所必需的,那么很难解释该方法为什么还要进行内部同步。(如果有必要,他们本可以/本可以使整个方法同步。)


  • 上述证据(国际海事组织)令人信服,但并非绝对证据。如果您想要证明
    interrupt()
    是线程安全的,您可以通过彻底分析
    interrupt0()
    的本机代码实现来获得它。我没有看过本机代码,但我认为
    interrupt0
    是内部线程安全的,这足以使
    中断
    方法线程安全。

    @xehpuk的问题值得更多关注:


    为什么它需要同步?在哪个物体上

    同步的全部意义——唯一意义——是保护数据不受损坏。当一个线程无法在不创建其他线程不能看到的临时无效状态的情况下推进程序状态时,我们使用同步

    在这种情况下,我们同步创建临时无效状态的代码块,并且还必须同步查看该状态的每个代码块

    那么,当我们谈论中断线程时,我们谈论的是什么状态

    不看代码,似乎只有两个:未中断和中断,它们都是有效的。从一个到另一个并没有明显的无效状态:从一个未中断到另一个中断就像一个原子操作。因此,一个合理的程序员会认为不需要同步


    当然,可能有一些我跳过的内部细节,但是内部细节应该对程序员隐藏。一个合理的程序员会期望,如果需要同步,那么它要么会在
    interrupt()
    方法中处理,要么会非常清楚地记录为调用方的责任。

    好问题,我希望
    interrupt0()
    要做到幂等和线程安全,但如果看不到实际的本机实现,就无法判断。@biziclop很可能你是对的。但是文档没有提到线程安全。也许,我必须参考
    interrupt0()
    的实现。你是对的,文档中没有提到这个问题。但是,如果
    Thread.interrupt()
    本身不是线程安全的,那么一切都会非常不稳定,因为无法保证它将从
    synchronized
    块调用,即使是,也无法保证这些块将在同一个锁对象上同步。为什么需要同步?关于哪个对象?@xehpuk很好的问题,正如我已经被告知的,如果方法不是线程安全的,那将是很奇怪的。AFAIK这就是
    blocker
    字段所负责的。如果设置为非空值,
    interrupt0()
    在内部同步。听起来非常合理。谢谢。顺便说一句,也许你知道这个方法是在哪里实现的。我的意思是,我可以在
    JDK
    提供的
    src.zip
    源代码中找到它吗?你不知道吗?你需要