如何比较线程对象
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);
}
我最近在 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);
}