问题
I recently came across the sources of AWT's EventQueue where I saw this piece of code:
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();
}
}
What really struggles me is that the thread objects are being compared using ==. So far I've been doing this with equals(Object). I already had a look at this question but the two answers aren't really what I'm looking for.
Is it possible that two different instances refer to the same native thread? How should I compare thread objects for equality?
回答1:
Is it possible that two different instances refer to the same native thread?
No.
According to the Thread javadoc:
A thread is a thread of execution in a program.
The life cycle of a Thread object has three phases:
Prior to the
start()call, aThreadobject denotes a thread that has yet to be created. And might never be created; i.e. ifstart()isn't called. (At this point, there is no native thread.)After the
start()call, and until therun()call terminates, theThreadobject denotes a live thread. (At this point, there is a native thread.)After the
run()call terminates, theThreadobject denotes a thread that no longer exists. (At this point the native thread that embodied the thread has been deleted.)
At no point does it make any sense for two distinct Thread objects to denote the same thread; i.e. the same thread of execution.
How should I compare thread objects for equality?
Using == is the right way.
But equals(Object) is also correct, because Thread inherits it from Object where it is defined to be the same as ==.
On the point of style.
Some would argue that is is stylistically better to use equals. However, it this context, the Thread javadoc (in effect) specifies that equals and == do the same thing. Indeed, reference equality is the only equality semantics that would make any sense for Thread objects. This follows from the way that the `Thread life-cycle works, and the fact two distinct threads of execution intuitively. (They could consistently produce the same results, but that is "emergent" behavior ... and proving that behavior is in general an intractable problem.)
On the other hand, this question wasn't about style. It was about whether == is semantically correct in this context.
回答2:
The first key thing here is: there can't be two threads that would be equal but have different references.
So in essence: this is one of the rare cases where using the check for equal references makes sense. Especially in a case where it is not about comparing an "arbitrary high" number of thread objects. You just one to make sure that the "current" thread is (not) some thread reference you stored earlier on.
Of course, one could also use equals(Object) to compare threads, and maybe that would be better to avoid to surprise readers. But on the other hand, this would be more of a "style" question; regarding an aspect that probably is not very common for 99% of the code that you read/write in your daily life.
And, as TJ Crowder correctly points out: Thread.equals(Object) translates to Object.equals(Object), which ... does a simple check for reference equality. Underlying the point that this is really style only. Which holds true, until people would start creating their own sub-classes of Thread and provide a different implementation of equals.
Finally, the second key thing is: two Java thread objects can not have the same underlying native threads.
回答3:
From JSL-17:
These threads independently execute code that operates on values and objects residing in a shared main memory
It means that each instance of thread will be executing independently of other instances, although the data can be shared between them. So, two instances cannot refer to same native thread.
As a general case, you should prefer equals(Object) for checking equality. But for Thread equality, you can use either == or equals(Object) method.
Source code of Thread.equals(Object) inherited from java.lang.Object:
public boolean equals(Object obj) {
return (this == obj);
}
来源:https://stackoverflow.com/questions/39972629/how-to-compare-thread-objects