2016-10-11 2 views
4

Недавно я наткнулся на источники АВТ-х 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, но два ответа на самом деле не то, что я ищу.

Возможно ли, что два разных экземпляра относятся к одному родному потоку? Как сравнить объекты нитей для равенства?

+1

Хех, один из тех забавных ситуаций, когда * вопрос * действительно дубликат, но ответы там не дают ответа на поставленный вопрос. :-) –

+3

Ключ к вашему вопросу заключается в том, будет ли 'Thread.currentThread() == eq.dispatchThread' когда-либо давать вам другой результат, чем' Thread.currentThread(). Equals (eq.dispatchThread) '.И ответ - нет, он никогда не будет, потому что ['Thread.currentThread'] (http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#currentThread--) будет никогда не возвращайте 'null' и' Thread' наследует 'equals' от' Object' и ['Object # equals'] (http://docs.oracle.com/javase/8/docs/api/java/lang/Object .html # equals-java.lang.Object-) делает '=='. –

+0

@ T.J.Crowder Я думал то же самое! ;) – beatngu13

ответ

6

Возможно ли, что два разных экземпляра относятся к одному родному потоку?

Номер

Согласно Thread Javadoc:

нить является потоком выполнения в программе.

Жизненный цикл Thread объекта состоит из трех фаз:

  • До start() вызова, Thread объекта обозначает нити, которую еще предстоит создать. И никогда не может быть создано; т.е. если start() не вызывается. (На данный момент, нет родной нити.)

  • После start() вызова, а также до тех пор, пока вызов run() завершается, Thread объект обозначает живую нити. (На данный момент, есть родную нить.)

  • После run() завершает вызов, Thread объекта обозначает нити, которая больше не существует. (В этот момент нативный поток, который воплотил нить был удален.)

Ни в одной точке он делает какой-то смысл для двух различных Thread объектов, обозначающих один и тот же нить; т.е. тот же поток выполнения.

Как сравнить объекты нитей для равенства?

Использование == - это правильный путь.

Но equals(Object) также верен, поскольку Thread наследует его от Object, где он определен как тот же, что и у ==.


На месте стиля.

Некоторые утверждают, что стилистически лучше использовать equals. Однако в этом контексте Thread javadoc (по сути) указывает, что equals и == делают то же самое. Действительно, ссылочное равенство является единственной семантикой равенства, которая имела бы смысл для объектов Thread. Это следует из того, как работает «Жизненный цикл потока», и факт двух отдельных потоков исполнения интуитивно. (Они могут последовательно давать одинаковые результаты, но это «возникновение» поведения ... и доказательство того, что поведение в целом является неразрешимой проблемой.)

С другой стороны, этот вопрос касался не стиля. Речь шла о том, является ли == семантически правильным в этом контексте.

2

Первый ключевой момент здесь: не может быть двух потоков, которые были бы равны, но имели разные ссылки.

Итак, по существу: это один из редких случаев, когда использование проверки для равных ссылок имеет смысл. Особенно в случае, когда речь идет не о сравнении «произвольного высокого» количества объектов потока. Вы только один, чтобы убедиться, что «текущий» поток (не) содержит некоторую ссылку на резьбу, которую вы сохранили ранее.

Конечно, можно было бы использовать equals(Object) для сравнения тем, и, возможно, лучше было бы избежать удивления читателей. Но, с другой стороны, это будет скорее вопрос «стиля»; в отношении аспекта, который, вероятно, не очень распространен для 99% кода, который вы читаете/пишете в своей повседневной жизни.

И, как правильно указывает TJ Crowder: Thread.equals(Object) переводит на Object.equals(Object), который ... делает простую проверку для ссылочного равенства. В основе лежит то, что это действительно только стиль. Это справедливо, пока люди не начнут создавать свои собственные подклассы Thread и не смогут реализовать различных эквивалентов.

Наконец, вторая ключевая вещь: Два объекта Java-потока не могут иметь одинаковые исходные потоки.

+2

Действительно, это сводится к стилю, поскольку 'Thread' наследует' equals' от 'Object' и [' Object # equals'] (http://docs.oracle.com/javase/8/docs/api /java/lang/Object.html#equals-java.lang.Object-) выполняет '=='. –

+0

Я так и думал; но не нашли времени, чтобы записать это так. Теперь; спасибо за ваш вклад! – GhostCat

+0

Я бы предложил, чтобы мы все удалили комментарии вокруг этого недопустимого поиска ;-) – GhostCat

1

От JSL-17:

Этих нитей независимо друг от друга выполнить код, который работает на значения и объектов, проживающий в общей оперативной памяти

Это означает, что каждый экземпляр нити будет выполнение независимо от других хотя данные могут быть разделены между ними. Таким образом, два экземпляра не могут ссылаться на один и тот же собственный поток.

В общем случае вы должны предпочесть equals(Object) для проверки равенства. Но для Thread равенства вы можете использовать метод == или equals(Object).

Исходный код Thread.equals(Object) унаследовал от java.lang.Object:

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

Ссылка для JSL-17 не работает для меня. – Jabir

+0

@Jabir исправлено, спасибо, что заметили. –

+0

Какие-либо причины для проголосовавших? –

Смежные вопросы