我正在编写一个游戏,其中一个线程 - GameThread - 永远循环,更新所有 Sprite ,渲染它们,然后 hibernate 一段时间,然后再次执行这一切。我还有一个定制的事件处理程序,用于处理按键等。
这在大多数情况下都可以正常工作。但是,如果在 GameThread 渲染时引发事件,我就会遇到问题。在极少数情况下,处理事件的处理程序可能会对需要渲染的内容进行并发更改,从而影响 GameThread 渲染的结果。
为了避免这种情况,我希望事件处理程序立即暂停 GameThread,处理事件,然后恢复 GameThread。
suspend()
/resume()
方法满足我的需求,但它们已被弃用。然而,就我而言,由于发生死锁的可能性很小,因此无论如何使用它们是否安全?如果没有,我还有哪些其他不会产生大量开销的替代方案?
我看到了一个建议,通过在要暂停的线程中设置一个标志来请求线程暂停。然而,就我而言,我认为这不是一个可行的选择,因为 GameThread 循环在循环迭代期间可能需要一段时间。在完成循环之前我将无法检查标志,但那时已经太晚了。
我需要立即暂停,否则用户会注意到事件处理的延迟。
最佳答案
如果要同步对资源的访问,请使用 ReentrantLock:
ReentrantLock 同步 = new ReentrantLock();
您必须将该锁传递给您想要访问共享数据的每个可运行程序。
然后在您访问相关资源的每个地方,您将使用该共享锁对象,并获取和释放锁(即您的关键部分):
sync.lock();
try {
// critical section code here
}
finally {
sync.unlock();
}
这是 Java 中相当标准的并发编程。请记住“lock”是一种阻塞方法,因此您可能需要使用“tryLock”来代替,它允许您尝试获取锁,但返回一个 boolean 值以确定您是否真正获得了锁:
if (sync.tryLock()) {
try {
//critical section
}
finally {
sync.unlock();
}
}
有一个“tryLock”版本,它会等待给定的时间,然后放弃尝试获取锁并返回错误值。
关于java - 如何通过使用暂停然后恢复或替代方案来同步线程之间的共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9952636/