У меня есть два потока, выполняющих вычисления по общей переменной «n», каждый поток увеличивает «n» каждый раз, а другое уменьшает «n» каждый раз, когда я не использую ключевое слово volatile для этой переменной , то я не могу понять, бывает, С.Б. там, пожалуйста, помогите объяснить, фрагмент кода, как следующие:Обмен переменной между потоками в JAVA
public class TwoThreads {
private static int n = 0;
private static int called = 0;
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
n = 0;
called = 0;
TwoThreads two = new TwoThreads();
Inc inc = two.new Inc();
Dec dec = two.new Dec();
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
while (called != 2) {
//System.out.println("----");
}
System.out.println(n);
}
}
private synchronized void inc() {
n++;
called++;
}
private synchronized void dec() {
n--;
called++;
}
class Inc implements Runnable {
@Override
public void run() {
inc();
}
}
class Dec implements Runnable {
@Override
public void run() {
dec();
}
}
}
1) Что я ожидаю это «п = 0, называется = 2» после выполнения, но вероятность того, что основной поток может быть заблокирован в цикле while;
2) Но когда я раскомментировать эту строку, программа, когда, как ожидается:
//System.out.println("----");
3) Я знаю, что я должен использовать «летучие» на «называется», но я не могу объяснить, почему выше происходит;
4) «called» is «read and load» в рабочей памяти определенного потока, но почему он не «сохраняет и записывает» обратно в основной поток после цикла «long» while, если это не так, почему простой " print "может сделать такую разницу
Я думаю, что вы можете получить тот же эффект, используя метод Thread.sleep() вместо print(). –
@victor вы правы, любая строка может иметь одинаковый эффект, не может объяснить, почему –
Ну, вы не контролируете, когда какой-либо поток выполняется; но основной будет продолжаться, и к тому времени, когда он завершит его, другой поток тоже будет. Вот почему вы должны использовать Thread.join(), чтобы остановить основной, пока остальная часть потока не завершится. (Thread.sleep() будет делать это в течение некоторого времени, но join() будет ждать до финиша) –