Как получить доступ к переменным в работающем объекте в Java - PullRequest
3 голосов
/ 03 января 2012

Я собираюсь смоделировать систему светофора. Я создал Road Class, который расширяет JFrame и реализует Runnable.

В методе run () я добавил логику для увеличения положения Y каждого автомобиля, и теперь он имитирует движение автомобилей. Но теперь мне нужно проверить состояние светофора, прежде чем двигать машину.

Это мой класс TrafficLight,

import java.util.Random;

public class TrafficLight implements Runnable {

volatile boolean stop;

public TrafficLight(boolean stop) {
    this.stop = stop;
}

@Override
public void run() {
    Random randomGenerator = new Random();
    while (true) {
        if (stop) {
            stop = false; //change current status
        } else {
            stop = true;  //change current status
        }
        try {
            Thread.sleep(2000 + randomGenerator.nextInt(2000));
        } catch (Exception ex) {
            System.out.println("error");
        }
       }
   }
}

Есть ли способ проверить эту изменчивую переменную stop из моего класса дорог.

Если нет, предложите мне другое решение для этого.

Спасибо.

Ответы [ 3 ]

7 голосов
/ 03 января 2012

Реализация средства доступа для остановки.

public class TrafficLight implements Runnable {

   volatile boolean stop;

   // Irrelevant code

   public boolean isStop() {
     return stop;
   }
}

Получите TrafficLight в конструкторе класса Road и используйте его для получения доступа к переменной stop

public class Road implements Runnable {

   private TrafficLight trafficLight;

   public Road (TrafficLight trafficLight) {
     this.trafficLight = trafficLight;     
   }

   @Override
   public void run() {
     // Irrelevant code
     if(trafficLight.isStop()) {
       // do something
     } 
   }
}
1 голос
/ 03 января 2012

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

НО доступ к этому свойству (стоп) должен быть защищен.ключевое слово volatile не очень помогает (см. ниже).

Я должен сделать что-то вроде:

private synchronized void toogleStopped() { // guarded
    this.stop = !this.stop;

}

public synchronized boolean isStopped() { // guarded
   return this.stop;
}

События

Если некоторые другиеобъект должен реагировать на изменения в освещении (реагировать на событие «свет изменился»), использовать шаблон проектирования Observer, как предложено @TejasArjun.

Почему volatile не помогает

volatile позволяет Java избегать предположения, что переменная не изменена "извне".Поэтому, если поток устанавливает свое значение (или читает его раньше), при втором чтении будет использоваться (возможно) кэшированное значение (уже сохраненное в регистре ЦП или что-то в этом роде).volatile заставляет Java всегда читать значение из памяти.

Сказал, что проблема с потерянным обновлением остается даже с ключевым словом volatile.Одной веткой можно 1) прочитать 2) написать.Другой поток может сделать то же самое.И они могут делать это в следующем порядке:

Поток 1 читает ложь Поток 2 читает ложь Поток 1 устанавливает истину (при условии, что он прочитал ложь) Поток 2 устанавливает истину (предполагая, что читается ложь)

это нехорошо:)

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

0 голосов
/ 03 января 2012

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

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