Указатель на объект в Java с несколькими потоками - PullRequest
3 голосов
/ 17 января 2011

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

Мне нужен первый поток для визуализации объекта в списке объектов 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?

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

Ответы [ 6 ]

4 голосов
/ 17 января 2011

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

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

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

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

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

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

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

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

Попробуйте пометить переменную rotation в объекте как volatile

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

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

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

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

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

Ваш первый поток, вероятно, работает перед вторым потоком.

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