Я пытаюсь синхронизировать пару потоков, не связанных с пользовательским интерфейсом, один поток для запуска игровой логики и один поток для рендеринга, чтобы выполнять задачи в логическом и эффективном порядке. Ограничение, которое я наложил на себя, заключалось в том, что вся система работает в устойчивом состоянии без распределения, поэтому все объекты отображения возвращаются и «перерабатываются», и поэтому два потока должны поддерживать своего рода двусторонний диалог, который возникает, когда я вызываю Метод swapBuffers().
В псевдокоде порядок событий в игровом потоке выглядит примерно так:
while(condition)
{
processUserInput();
runGameLogicCycle(set number of times);
waitForBuffersSwapped();
unloadRecycleBuffer(); //This function modifies one buffer
loadDisplayBuffer(); ///This function modifies another buffer
waitForRenderFinished();
renderThread.postTask(swapBuffersAndRender);
}
Поток рендеринга выбирается для выполнения задачи по замене буферов таким образом, чтобы поток игровой логики мог тем временем выполнять задачи, которые не изменяют буферы. В своем коде я комбинирую задачу замены буферов и рендеринга и определяю его как объект Runnable, который отправляется обработчику потока рендеринга. В псевдокоде этот исполняемый файл выглядит примерно так:
{
//Swap the buffers
}
gameThread.notifyThatBuffersSwapped();
{
//Render items to screen
}
gameThread.notifyThatItemsRendered();
Моя проблема связана с реализацией. Я знаком с концепциями обработчиков, блоков синхронизации и ReentrantLocks. Я знаю о методах Lock.await() Lock.signal(), но мне кажется, что документации недостаточно, чтобы понять, как они ведут себя при вызове в цикле итераций.
Как реализовать ReentrantLocks, чтобы заставить два потока ожидать друг друга таким образом? Пожалуйста, включите практическую идиому в свой ответ, если это возможно.