Java 线程交换导致的延迟

Java 线程交换导致的延迟,java,eclipse,multithreading,jvisualvm,awt-eventqueue,Java,Eclipse,Multithreading,Jvisualvm,Awt Eventqueue,我最近在开发的一款游戏中遇到了一些滞后峰值。这是一致的,几乎同时发生。使用java探查器jvisualvm,我发现它发生在某个特定线程似乎重新启动或发生其他事情的同时(AWT-EventQueue-0): 除此之外,没有任何可见的原因,不是堆使用、处理器使用、内存空间或方法使用。在绘制我的对象数组时,它有时会导致ConcurrentModificationException,但这种情况只会在相当长的延迟时间内发生,而且我的游戏强度很小 我不记得最近对项目进行过任何更改,但我最近进行了以下工作:

我最近在开发的一款游戏中遇到了一些滞后峰值。这是一致的,几乎同时发生。使用java探查器jvisualvm,我发现它发生在某个特定线程似乎重新启动或发生其他事情的同时(AWT-EventQueue-0):

除此之外,没有任何可见的原因,不是堆使用、处理器使用、内存空间或方法使用。在绘制我的对象数组时,它有时会导致
ConcurrentModificationException
,但这种情况只会在相当长的延迟时间内发生,而且我的游戏强度很小

我不记得最近对项目进行过任何更改,但我最近进行了以下工作:

  • 将java更新至最新版本
  • 下载了JDK7的最新版本(尽管本项目未使用该版本)
  • 修复了eclipse在安装JDK7时出现的错误(删除了256m限制) 在eclipse.ini中)
我正在32位XP上运行EclipseIndigo-service-1。我的处理器很少使用。

似乎您在事件调度线程(EDT)上做得太多了。AWT-Event-Queue-0看起来是EDT。另外,你最后的评论说

…似乎只有当我首先将游戏板绘制到图像上,而不是直接绘制到组件上时,才会出现滞后峰值

您将需要将一些计算推送到其他线程,而且看起来绘制游戏板是一个很好的选择。还有,任何你可能有的人工智能

您的键盘和鼠标处理程序在EDT上运行,图形更新也需要在EDT上运行。但您可以在EDT之外预渲染到图像(就像您当前所做的那样)。您可以通过BlockingQueue将键盘和鼠标事件发送到另一个线程

你可以做的另一件事是将你的游戏更新率从你的帧更新率中分离出来

但是如果没有任何细节,我不能给出更多的建议

更新:(只需阅读有关
ConcurrentModificationException的内容

这可能是由两种不同的原因造成的:

  • 在不同的线程中更新集合(如ArrayList),该线程与读取集合的线程不同;或
  • 您正在迭代所述集合并在循环中更新它

  • 第二点容易修正;但我恐怕无法在这么短的空间内教授线程安全。

    什么是“滞后尖峰”?你是如何测量它的?当线程“重新启动”时,它在做什么?延迟峰值是指游戏在大约每秒3帧左右的时间内结束,它是可见的,实际上使游戏无法进行,因为它是一个反应类型的游戏。我不知道线程在做什么,我甚至不知道线程是用来做什么的。如果您愿意,我可以从jvisualvm获取线程转储?让我注意,我正在做的唯一线程处理是在初始化时开始游戏循环。@PerryMonshau AWT-EventQueue-0是。您在该线程上所做的某些操作导致它阻塞,从而导致应用程序无响应。我们将需要检查您的代码以查看发生了什么。
    ConcurrentModificationException
    s的问题可能是因为您的游戏循环没有在EDT上运行,并且您没有处理并发问题。(另外,知道在没有代码本身的情况下使用哪些导入几乎是无用的。)如果您想了解更多关于并发性的信息,请参阅入门指南。