отношения «до того» не работают должным образом с использованием «volatile» - PullRequest
0 голосов
/ 30 октября 2018
int x,y;
volatile int z;

public static void main(String[] args) {
    ThreadPoolExecutor pool = (ThreadPoolExecutor)Executors.newFixedThreadPool(5);
    MainTest mission = new MainTest();
    pool.execute(new MissionRead(mission));

    pool.execute(new MissionWrite(mission));
            pool.execute(new MissionWrite(mission));

    pool.shutdown();
}

public void set() {
    System.out.println("set start");
    x++;

    y++;z++;

    System.out.println("set end");

}

public void get() {
    System.out.println(Thread.currentThread().getName() +": get start");
    System.out.println(Thread.currentThread().getName() +": z is " + z);
    System.out.println(Thread.currentThread().getName() + ": x is " +  x);
    System.out.println(Thread.currentThread().getName() +": y is " + y);
    System.out.println(Thread.currentThread().getName() +": get end");

}

вывод: pool-1-thread-1: начало работы
установить начало
установить конец
установить начало
установить конец
pool-1-thread-1: z равно 0
пул-1-нить-1: х равен 2
пул-1-нить-1: у 2
pool-1-thread-1: получить конец

ожидаемый результат: pool-1-thread-1: получить начало установить начало
установить конец
установить начало
установить конец
pool-1-thread-1: z равен 2
пул-1-нить-1: х равен 2
пул-1-нить-1: у 2
pool-1-thread-1: получить конец

почему в выводе не отображается обновленное значение z с изменчивыми ключевыми словами.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

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

public synchronized void set() {
    System.out.println("set start");
    x++;
    y++;
    z++;
    System.out.println("set end");
}
0 голосов
/ 30 октября 2018

Это потому, что volatile просто принудительно считывает основную память для любого атомарного действия, выполняемого с ним / с ним, но z++ эквивалентно z = z + 1, что означает, что там есть 2 действия: чтение операция и операция записи. Несколько потоков могут по-прежнему читать / записывать значение между этими двумя операциями.

...