java - 如何通过使用暂停然后恢复或替代方案来同步线程之间的共享数据

标签 java multithreading resume suspend

我正在编写一个游戏,其中一个线程 - GameThread - 永远循环,更新所有 Sprite ,渲染它们,然后 hibernate 一段时间,然后再次执行这一切。我还有一个定制的事件处理程序,用于处理按键等。

这在大多数情况下都可以正常工作。但是,如果在 GameThread 渲染时引发事件,我就会遇到问题。在极少数情况下,处理事件的处理程序可能会对需要渲染的内容进行并发更改,从而影响 GameThread 渲染的结果。

为了避免这种情况,我希望事件处理程序立即暂停 GameThread,处理事件,然后恢复 GameThread。

  1. suspend()/resume() 方法满足我的需求,但它们已被弃用。然而,就我而言,由于发生死锁的可能性很小,因此无论如何使用它们是否安全?

  2. 如果没有,我还有哪些其他不会产生大量开销的替代方案?

我看到了一个建议,通过在要暂停的线程中设置一个标志来请求线程暂停。然而,就我而言,我认为这不是一个可行的选择,因为 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/

相关文章:

python - 在守护线程中创建的进程的主线程是守护进程本身是Python错误吗?

java - 命令..休息;在 Java 中,如果.?

Java - Android Studio - .xml 文件不存在错误

linux - X个线程是通过X个进程实现的吗?

recovery - 抗电源/硬件/操作系统故障的程序

xcode - 从我们的应用播放声音时暂停ipod,然后恢复播放

javascript - 检索事件列表

java - 如何用整数打印点数组?

java - 为什么 java 字符串在 MYSQL 中没有保存为 UTF-8?

node.js - Expressjs多线程