Показать разницу между volatile и обычной переменной в Java - PullRequest
3 голосов
/ 20 апреля 2011

Я пытаюсь создать пример для отображения разницы между переменными и обычными переменными, такими как:

package main;

public class TestVolatile extends Thread {

    public int l = 5;
    public volatile int m = -1;

    public TestVolatile(String str) {
        super(str);
    }

    public void run() {
        int i = 0;
        while ((l > 1) && (l < 10)) {
            if (m >= 0) {
                m++;
            }
            i++;
            l = 5;
            System.out.println("5=" + i + " m=" + m);
        }

    }

    public static void main(String[] args) throws InterruptedException {
        TestVolatile tva = new TestVolatile("ThreadA");

        tva.start();
        sleep(5);
        synchronized (tva) {
            tva.m = 5;
            tva.l = 10;
        }
    }

}

То есть m является изменчивым, l - нет. Я полагаю, что выход из цикла while зависит от значения l.
Поскольку значение l не является энергозависимым - m будет увеличиваться как минимум 1 раз после присвоения l 5. Но я запускал код 10 раз и всегда m == 5.
Поэтому я полагаю, что я не прав. Как решить эту проблему? Спасибо.

Спасибо за ответы, но не все хорошо. Я установил как:

volatile int x = 0;
volatile int y = 0;

Так что теперь переменные должны быть одинаковыми! Но это не тот случай.

x: 346946234 y: 346946250
x: 346946418 y: 346946422
x: 346946579 y: 346946582
x: 346946742 y: 346946745
x: 346946911 y: 346946912

Ответы [ 2 ]

4 голосов
/ 20 апреля 2011

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

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

Следующая программа показывает на моем компьютере разницу между переменными и энергонезависимыми переменными.

public class ShowVolatile {

    final static int NUM_THREADS = 1;

    int x = 0;
    volatile int y = 0;

    public static void main(String... args) {

        final ShowVolatile sv = new ShowVolatile();

        for (int i=0; i< NUM_THREADS; i++) {
            new Thread(new Runnable() {
                public void run() {
                    while (true) {
                        sv.x += 1;    
                        sv.y += 1;    
                    }
                }
            }).start();
        }


        while (true) {
            System.out.println("x: " + sv.x + " y: " + sv.y);
        }
    }

}

Если вы увеличите количество потоков, вы увидите дополнительные пропуски синхронизации.Но количество потоков 1 достаточно.По крайней мере, на моем оборудовании Quad-Core i7.

2 голосов
/ 20 апреля 2011

Наличие нескольких потоков, выполняющих одновременную несинхронизацию ++ для вашей переменной volatile, должно помочь. Однако это никогда не будет детерминированным. Это также может зависеть от операционной системы и процессора.

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