Является ли java.lang.Thread самим потокобезопасным классом? - PullRequest
7 голосов
/ 19 февраля 2012

Мне было интересно, нужна ли нам внешняя синхронизация для использования методов в java.lang.Thread ?

Например, можем ли мы вызвать метод t1.isAlive () из any thread без внешней синхронизации и ожидайте, что она вернет:

true, если t1 уже запущен, false в противном случае.

Или требуется внешняя синхронизация для вызова методов в java.lang.Thread ?

public static void main(String args[]) {
        final java.lang.Thread t1 = new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                while(true){
                    //task
                }
            }
        });
        java.lang.Thread t2 = new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                while (true) {
                    System.out.println(t1.isAlive()); // do we need synchronization before calling isAlive() ?
                }
            }
        });
        t2.start();
        t1.start();
        try {
            java.lang.Thread.sleep(1000000);
        } catch (java.lang.InterruptedException e) {
            e.printStackTrace();
        }
    }

1 Ответ

4 голосов
/ 19 февраля 2012

Да, это уже должно быть поточно-ориентированным.Вы можете посмотреть исходный код Thread.java здесь , все важные методы, такие как запуск и т. Д., Синхронизированы.

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

Однако метод start проверяет переменную-член threadStatus, прежде чем приступить к ее работе, и это изменчивое целое число, то есть оно будет мгновенно обновлено во всех обращающихся потоках.Таким образом, вы можете использовать вызов getState, чтобы проверить, запущен ли поток, а не метод isAlive, чтобы избежать запуска вызова дважды.Я скопировал соответствующие части Thread.java ниже.

/* Java thread status for tools,
 * initialized to indicate thread 'not yet started'
 */

private volatile int threadStatus = 0;

...

public synchronized void start() {
    /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
     */
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
....

public State getState() {
    // get current thread state
    return sun.misc.VM.toThreadState(threadStatus);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...