Котлин, проблема гонки

Соответствующий код здесь

По сути, у нас есть два потока, один из которых ведет рендеринг, который продолжает вызывать display() и другой, который заботится о пользовательских вводах, вызывая соответствующее событие мыши или ключа соответственно

Поля полюса и объекта – это не что иное, как вспомогательные классы для облегчения обработки матрицы относительно камеры и объекта (ов).

Их методы называются как из display() и из методов ввода пользователя.

display() вызывает как viewpole.calcMatrix() и objectpole.calcMatrix() то время как входной поток вызывает их косвенно, например basicLighting.mouseDragged() -> objectpole.mouseDragged() -> rotateView() -> calcMatrix()

Состояние гонки начало появляться, когда я начал использовать объекты пула для уменьшения давления GC в конкретных сценариях. Я проверил десятки раз, каждый объект используется только один раз (кроме того, when ).

Я обнаруживаю состояние гонки, распечатывая матрицу вида каждый вызов display() . Когда бы он ни отличался, это значит, что я получил его. Пример здесь .

Исследуя, я узнал, используя простой println , например, что Viewpole.calcMatrix() иногда вызывался, пока другой вызов не завершил его полностью.

Добавление @Synchronized на каждом calcMatrix() (viewpole и objectpole) значительно уменьшило его, я бы сказал, 80/90%.

Но все же, несколько раз, я испытываю расовое состояние. Я попытался synchronize(lock){} также каждый вызов из пользовательского потока ввода, как здесь :

 val lock = Any() override fun mousePressed(e: MouseEvent) { synchronized(lock) { viewPole.mousePressed(e) objectPole.mousePressed(e) } } 

Это не помогло.

Что я делаю не так? И какой правильный способ реализовать синхронизацию для моего случая? То есть два потока, вызывающих один и тот же класс.

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

Что вы делаете неправильно, трудно сказать, не пересматривая весь ваш код. Но вот несколько советов: / viewPole.calcMatrix () возвращает ссылку на mat4_B. В display () эта ссылка используется за пределами синхронизированного блока. Таким образом, mat4_B потенциально может быть изменен одновременно при использовании display () / viewPole.calcMatrix (), а objectPole.calcMatrix () вызывается в отдельных синхронизированных блоках. Таким образом, матрица viewPole может быть основана на другом состоянии, а затем на объектной матрице. Я не могу сказать, является ли это проблемой для вашего случая использования.

Подход должен состоять в том, чтобы: / уменьшить общее состояние как можно больше (т.е. путем передачи копий) / выборки всех данных в одной, атомной (синхронной) операции

Intereting Posts
Проблема с Kotlin после Android Studio была обновлена ​​до 0,6 Параметр, заданный как ненулевой, равен null в массиве ArrayAdaper Откуда берутся три тестовых контейнера? Котлинское умножение между обнуляемыми и невалютными ошибками float даже с нулевой проверкой Могут ли в производстве использоваться «экспериментальные» Kotlin-сопрограммы? Избегайте приостановления другого приложения для аудиозаписей на YouTubePlayerFragment init Получите результат от Observable – Kotin Android Приложение Kotlin не показывает мой json-массив Есть ли способ отфильтровать null Any? ценностей на карте Котлина? Работа для администратора устройства api не имеет собственного профиля Сохранять двойные кавычки при получении элемента из JSONArray Kotlin HashMap содержит ключи, используя массив Android – Kotlin – остановка в середине процесса RxJava: Отменить подписку async, наблюдаемую из другого асинхронного производства Котлин: проблемы с пониманием дженериков