Необъяснимые махинации Java - возможно, делать с многопоточностью? - PullRequest
3 голосов
/ 21 января 2011

Проблема

Сейчас я на полпути к созданию симулятора Game of Life на Java (в Eclipse) с использованием графического интерфейса Swing как части проекта для колледжа.Это происходит удивительно, за исключением одного небольшого недостатка -

. Он работает на моем нетбуке, но не на любом другом ПК, который я пробовал.Это под Ubuntu.

Некоторая структурная схема - у меня есть Модель, Вид и Контроллер.Я еще не определил модель должным образом, но я сделал вид (часть с графическим интерфейсом) и запустил контроллер.Контроллер запускается методом Main, а затем Controller создает класс View в отдельном потоке и входит в цикл while.

Представление реализует очередь «заказов», которые он получил от пользовательского ввода, щелчков мышью, а что нет.Контроллер выбирает эти заказы из очереди на итерации цикла while и выполняет их по мере необходимости.

Однако, хотя код отлично работает на моем нетбуке (последняя версия, Java 1.6.0_20), он не работает на моем ПК (последняя версия Java 1.6.0_20) или на компьютерах колледжа (karmic)., некоторая предыдущая версия Java).Он просто останавливается при попадании в метод getNextCommand. Нет ошибок, просто отказывается печатать / соблюдать

Здесь находятся исходные файлы - http://www.mediafire.com/?dfwtdkj1tdxd5xl Интересующие файлы - Controller и View.

Пример

В View у меня есть эта функция:

public Command getNextCommand() {
  System.out.println(commands.getFirst().id);
  return commands.pop(); 
 }

Довольно понятно, когда контроллер вызывает getNextCommand (), он печатает, какая это была команда.

Вот цикл while в Controller:

while(!stop) {
   if (gui.hasCommand()){
    order = gui.getNextCommand();
    //System.out.println("Something");
    //if(order.id.equals("stop")) { stop = true; }
   }
  }

Это прекрасно работает.Он печатает в getNextCommand, как и следовало ожидать.

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

Почему это случилось?Почему это работает на моем нетбуке, а не на моем ПК?: C

Дополнительные примечания

Кроме того, если я запускаю файлы .class, которые создает Eclipse, он печатает (при условии, что эти две строки закомментированы).Если я просто скомпилирую их, используя javac, ничего не печатается.

Любое понимание будет оценено!

Спасибо,

Люк.

Редактировать

Та же проблема возникает, если вместо возврата команды (простой контейнерный класс с идентификатором (String), x, y (int) и value (int)), когда я вызываю getNextCommand, я возвращаю Integer.Или что-нибудь еще.

Ответы [ 3 ]

3 голосов
/ 21 января 2011

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

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

Подробнее здесь: http://gee.cs.oswego.edu/dl/cpj/jmm.html

Быстрое решение: используйте java.util.vector вместо LinkedList

2 голосов
/ 21 января 2011

Нам нужна дополнительная информация.Какой тип commands?

В любом случае, лучшее решение, чем занятое ожидание (вращение в цикле while), это иметь какой-то механизм ожидания / уведомления.Кажется, очевидным кандидатом для вашей проблемы является BlockingQueue (например, ArrayBlockingQueue или LinkedBlockingQueue).Методы поиска этого типа блокируют до тех пор, пока не появятся доступные данные (команда), вместо того, чтобы требовать от вас постоянного опроса, пока не появится доступная команда.

Например:

BlockingQueue<Command> commands = new LinkedBlockingQueue<Command>();

//...

//wait for the next element and then get it
while(!stop) {
   Command nextCommand = commands.take();
   //do something with nextCommand
}

Ссылки

0 голосов
/ 21 января 2011

Скорее всего, есть ошибка, которую вы не перехватываете или неправильно обрабатываете. Дважды проверьте, что вы не выбрасываете исключения.

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

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