2011-01-17 3 views
3

У меня есть два потока. Один поток имеет экземпляр myObjectManager. myObjectManager имеет список объектов и метод для извлечения объекта (public myObjectClass getObjectById (int ID))Указатель объекта в Java с несколькими потоками

Мне нужен первый поток для рендеринга объекта в списке объектов myObjectManagers, а второй поток для выполнения логики игры и переместить его вокруг и т.д.

Это то, что я пытался

//thread 1: 
m = myObjectManager.getObjectById(100); 
m.render(); 

//thread 2: 
m = myObjectManager.getObjectById(100); 
m.rotate(m.getRotation() + 5); //increment rotation value 

Тем не менее, кажется, что нить 1 имеет экземпляр объекта без обновленного вращения. Когда я запускаю его, визуализируемый объект не вращается, но когда я делаю второй поток, распечатайте его значение поворота.

В C++ я бы просто сделал функцию getObjectById() вернет указатель на экземпляр myObjectClass, но я не уверен, что именно java делает, когда я говорю «return myInstance»; Как мне сделать что-то подобное в java?

Извините, новичок на этом языке!

+0

Являются ли ваши объекты потокобезопасными? – SLaks

+0

Что вы подразумеваете под этим? – AlexRamallo

ответ

4

В Java все переменные объекта являются «указателями» (или «ссылками», как обычно говорят люди). Проблема должна быть в другом месте. Я предполагаю, что поток 1 уже отобразил объект до того, как поток 2 даже изменил его.

Редактировать: Другая теория: последующие операции render() фактически не меняют экран. Значение вращения обновляется просто отлично - но оно не отражается на дисплее.

+0

Даже если это так, в потоке 1 используется m.rotation для рендеринга вращения. это значение не получает сброс или что-то еще, и ТОЛЬКО место его модификации находится в конструкторе myObjectClass (чтобы установить его в 0) и в методе запуска потока 2 – AlexRamallo

+1

@AlexRamallo: я не вижу противоречия. A. вы создаете объект; вращение равно 0. B. Нить 1 запускает его и отображает. Вращение равно 0. C. Резьба 2 запускает его, изменяет вращение и видит изменение вращения. Ничего не изменилось в рендеринг, поскольку рендеринг уже был выполнен раньше. –

+0

Heres image Я попытался объяснить, что я имею в виду: http://img694.imageshack.us/img694/5438/explains.jpg Оба потока работают бок о бок, поэтому, если они обращаются к одному экземпляру m, то неважно, какой из них происходит первым, потому что Thread 1 только READS, а thread 2 - это WRITES. Если поток 1 отображается до того, как поток 2 изменит поворот, то поворот должен быть виден в следующем кадре. EDIT: вращение никогда не сбрасывается – AlexRamallo

3

Ссылки (указатели) в порядке, но в Java каждому потоку разрешено создавать локальные копии объектов (думайте об этом как кэш), с которыми они работают, и если они не синхронизированы каким-либо образом, изменения, сделанные один поток не может быть видимым другому.

This учебник, надеюсь, поможет.

0

Все объекты в Java передаются по ссылке.
Невозможно написать код, который делает то, что вы пытаетесь сделать.

Ваша первая нить, вероятно, работает перед второй нитью.

0

Все ссылки на объекты в Java, как и ваши переменные m, являются на самом деле указателями.

Итак, в вашем примере обе переменные m указывают на один и тот же объект.

1

Try испачкать rotation переменные в объекте, как volatile

2

У вас есть 2 потенциальных проблемы, оба из которых были изложены здесь в разных ответах.

  1. Вы не дают никаких указаний на любой контроль упорядочения ваших операций резьбы . Поэтому рендер может произойти до обновления .Это предполагает, что задействованные классы фактически являются threadsafe и будут вести себя как ожидаемые .
  2. Если классы не поточно (т.е. синхронизировано каким-то образом), то обновления для вращения нити никогда не может рассматриваться в рендеринга нити.

Чтобы точно знать, что нам нужно будет найти источник для m класс. Кроме того, у вас могут возникнуть проблемы с getObjectById(), если они также не являются потокобезопасными.

Смежные вопросы