Java 如何比较线程对象

Java 如何比较线程对象,java,multithreading,concurrency,Java,Multithreading,Concurrency,我最近偶然发现了AWT的源代码,在那里我看到了这段代码: final boolean isDispatchThreadImpl() { EventQueue eq = this; pushPopLock.lock(); try { EventQueue next = eq.nextQueue; while (next != null) { eq = next; next = eq.nextQu

我最近偶然发现了AWT的源代码,在那里我看到了这段代码:

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)
进行此操作。我已经看过了,但这两个答案并不是我真正想要的

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

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

没有

根据
线程
javadoc:

线程是程序中的执行线程

线程
对象的生命周期有三个阶段:

  • 在调用
    start()
    之前,
    Thread
    对象表示尚未创建的线程。可能永远不会被创造;i、 e.如果未调用
    start()
    。(此时,没有本机线程。)

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

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

两个不同的
Thread
对象表示同一个线程毫无意义;i、 e.相同的执行线程

如何比较线程对象的相等性

使用
==
是正确的方法

但是
equals(Object)
也是正确的,因为
Thread
Object
继承了它,在那里它被定义为与
=
相同


就风格而言

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


另一方面,这个问题与风格无关。这是关于在这个上下文中
==
在语义上是否正确的问题。是的。

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

所以本质上说:这是使用相等引用检查有意义的少数情况之一。特别是在不涉及比较“任意高”数量的线程对象的情况下。您只需要确保“当前”线程是(不是)之前存储的某个线程引用

当然,我们也可以使用
equals(Object)
来比较线程,也许这样可以更好地避免让读者感到惊讶。但另一方面,这更像是一个“风格”问题;对于日常生活中99%的读/写代码来说,这可能不是很常见的方面

而且,正如TJ Crowder正确指出的:
Thread.equals(Object)
转换为
Object.equals(Object)
,这。。。对引用相等性进行简单检查。这实际上只是一种风格。这是正确的,直到人们开始创建自己的线程子类并提供不同的equals实现

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

来自:

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

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

一般情况下,您应该选择
equals(Object)
来检查相等性。但是对于
线程
相等,可以使用
=
相等(对象)
方法

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

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

嘿,其中一个有趣的情况是,问题确实是重复的,但那里的答案没有回答所问的问题。:-)问题的关键在于
Thread.currentThread()==eq.dispatchThread
是否会给您提供与
Thread.currentThread().equals(eq.dispatchThread)
不同的结果。答案是否定的,它永远不会,因为它永远不会返回
null
Thread
Object
继承
equals
,并且做
==
@T.J.Crowder我也在想同样的事情!;)线程t1=新线程();线程t2=新线程();系统输出println(t1等于(t2));我们可以这样做吗?意味着我们可以比较指向一个对象的两个线程引用吗?谢谢。是的,你能行。正如我的回答所说,
=
等于
都是测试两个线程是否相同的正确方法。(在您的示例中,输出将是
false
,因为
t1
t2
是不同的线程。)