如何比较线程对象

时间:2016-10-11 07:49:38

标签: java multithreading concurrency

我最近遇到了AWT EventQueue的来源,在那里我看到了这段代码:

final boolean isDispatchThreadImpl() {
    EventQueue eq = this;
    pushPopLock.lock();
    try {
        EventQueue next = eq.nextQueue;
        while (next != null) {
            eq = next;
            next = eq.nextQueue;
        }
        if (eq.fwDispatcher != null) {
            return eq.fwDispatcher.isDispatchThread();
        }
        return (Thread.currentThread() == eq.dispatchThread);
    } finally {
        pushPopLock.unlock();
    }
}

真正困扰我的是使用==比较线程对象。到目前为止,我一直在使用equals(Object)执行此操作。我已经看过this question,但这两个答案并不是我想要的。

两个不同的实例是否可能引用相同的本机线程?我应该如何比较线程对象的相等性?

3 个答案:

答案 0 :(得分:7)

  

两个不同的实例是否可能引用相同的本机线程?

没有

根据Thread javadoc:

  

线程是程序中执行的线程。

Thread对象的生命周期分为三个阶段:

  • start()调用之前,Thread对象表示尚未创建的线程。也许永远不会被创造出来;即如果没有调用start()。 (此时,没有本机线程。)

  • start()调用之后,直到run()调用终止,Thread对象表示实时线程。 (此时,有一个本机线程。)

  • run()调用终止后,Thread对象表示不再存在的线程。 (此时,已删除体现线程的本机线程。)

两个不同的Thread对象在任何时候都没有任何意义来表示相同的线程;即同一个执行线程。

  

我应该如何比较线程对象的相等性?

使用==是正确的方法。

equals(Object)也是正确的,因为ThreadObject继承了==,其定义与equals相同。

关于风格。

有些人认为使用Thread在风格上更好。但是,在此上下文中,equals javadoc(实际上)指定==Thread执行相同的操作。实际上,引用相等是唯一对==对象有意义的等式语义。这是从“线程生命周期”的工作方式,以及两个截然不同的执行线程的事实。 (他们可以始终如一地产生相同的结果,但这是“紧急”行为......并证明行为通常是一个棘手的问题。)

另一方面,这个问题与风格无关。这是关于let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil) let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") 在这种情况下是否在语义上是正确的。

答案 1 :(得分:2)

这里的第一个关键是:不能有两个相同但具有不同引用的线程

所以从本质上讲:这是使用检查相同参考的少数情况之一。特别是在不是要比较任意高的"线程对象的数量。你只需要确保"当前" thread是(之前)存储的一些线程引用。

当然,也可以使用ProcessBuilder.redirectOutput(new File("/dev/null")); 来比较线程,也许最好避免让读者感到惊讶。但另一方面,这将更像是一种风格"题;关于你在日常生活中读/写的99%代码可能不常见的一个方面。

并且,正如TJ Crowder正确指出的那样:equals(Object)转换为Thread.equals(Object),其中...对参考相等性进行了简单的检查。这是真正的风格的基础。这是正确的,直到人们开始创建他们自己的Thread子类并提供不同的 equals实现。

最后,第二个关键是:两个Java线程对象不能具有相同的底层本机线程

答案 2 :(得分:1)

来自JSL-17

  

这些线程独立执行对值和操作的代码   驻留在共享主存储器中的对象

这意味着每个线程实例将独立于其他实例执行,尽管数据可以在它们之间共享。因此,两个实例不能引用相同的本机线程。

作为一般情况,您应该更喜欢equals(Object)来检查相等性。但是,对于Thread平等,您可以使用==equals(Object)方法。

Thread.equals(Object)继承自java.lang.Object的源代码:

public boolean equals(Object obj) {
        return (this == obj);
    }