Должна ли следующая Java-программа выводить «num: 1 m_i: 2» из-за порядка синхронизации - PullRequest
4 голосов
/ 17 июля 2011

Я просто хочу проверить, правильно ли мое понимание правила синхронизации запуска потока JMM:

Должна ли следующая Java-программа выводить «num: 1 m_i: 2» только из-за следующего порядка синхронизации.

http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4.4


Действие, которое запускает поток, синхронизируется с первым действием в потоке, которое он запускает.

public class ThreadHappenBefore {
    static int num;
    int m_i;

    public static void main(String[] args) {
        final ThreadHappenBefore hb = new ThreadHappenBefore();
        num = 1;
            hb.m_i = 2;

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("num:"+num);
                System.out.println("m_i:"+hb.m_i);
            }
        }).start();
    }
}

Ответы [ 5 ]

1 голос
/ 17 июля 2011

Все, что закодировано до , гарантируется, что произойдет другой код до другого кода в данном потоке , когда более ранний код влияет на более поздний код . Поскольку начало потока кодируется после назначений, и назначений влияют на результаты операторов печати , эти назначения являются "видимыми" (т. Е. Случались раньше) код, который их печатает.

Однако, нет такой гарантии влияния порядка исполнения при просмотре из другого потока.

РЕДАКТИРОВАНИЕ (спасибо комментаторам)

Добавлено уточнение (выделено жирным шрифтом) к вышеприведенному относительно переупорядочения.

0 голосов
/ 17 июля 2011

Нет, он печатает правильную вещь из-за отношения "до" в разделе 17.4.5 .Если вы посмотрите на обсуждение ниже этого раздела, там также четко указано:

Вызов функции start () в потоке происходит до любых действий в запущенном потоке.

и более того:

Если x и y являются действиями одного и того же потока и x предшествует y в программном порядке, то hb (x, y).

Таким образом, два назначения гарантированно произошли до чтения в потоке.

У вас нет синхронизации в вашем примере.

0 голосов
/ 17 июля 2011

Поскольку до сих пор никто, кроме Стивена С в комментарии, не опубликовал правильный ответ: создание потока (начало (), а не новая тема ()!) Обеспечивает связь "до того, как произойдет".

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

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

0 голосов
/ 17 июля 2011

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

0 голосов
/ 17 июля 2011

Что 'порядок синхронизации'?Здесь нет синхронизации.Это просто нормальный порядок исключения.Все назначения происходят до того, как поток даже запускается.Я не знаю, почему это считается загадочным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...