如何比较线程对象

How to compare thread objects

我最近在 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,但这两个答案并不是我要找的。

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

Is it possible that two different instances refer to the same native thread?

没有

根据 Thread javadoc:

A thread is a thread of execution in a program.

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

  • start() 调用之前,Thread 对象表示尚未创建的 线程。并且可能永远不会被创造;即如果 start() 没有被调用。 (此时,没有原生线程。)

  • start() 调用之后,直到 run() 调用终止,Thread 对象表示一个活动的 线程. (此时,有一个原生线程。)

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

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

How should I compare thread objects for equality?

使用==是正确的方法。

但是 equals(Object) 也是正确的,因为 Thread 继承自 Object ,它被定义为与 ==.

相同

关于风格

有些人会争辩说使用 equals 在文体上更好。然而,在这种情况下,Thread javadoc(实际上)指定 equals== 做同样的事情。实际上,引用相等性是唯一对 Thread 对象有意义的相等性语义。这是从“线程生命周期”的工作方式以及两个不同的执行线程直观的事实得出的。 (他们可以始终如一地产生相同的结果,但那是“紧急”行为......并证明这种行为通常是一个棘手的问题。)

另一方面,这个问题与风格无关。这是关于 == 在这种情况下在语义上是否正确。确实如此。

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

所以本质上:这是使用检查相等引用有意义的罕见情况之一。特别是在不比较 "arbitrary high" 个线程对象的情况下。您只需确保 "current" 线程是(不是)您之前存储的某个线程引用。

当然,也可以用equals(Object)来比较线程,或许这样可以避免给读者带来惊喜。但另一方面,这更像是一个 "style" 问题;关于您 read/write 日常生活中 99% 的代码可能不太常见的方面。

而且,正如 TJ Crowder 正确指出的那样:Thread.equals(Object) 转换为 Object.equals(Object),它...对引用相等性进行简单检查。从根本上说,这实际上只是风格。在人们开始创建自己的 Thread 子 类 并提供 equals 的 different 实现之前,这是正确的。

最后,第二个关键的事情是:两个Java线程对象不能有相同的底层原生线程

来自JSL-17

These threads independently execute code that operates on values and objects residing in a shared main memory

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

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

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

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