摆脱潜在的僵局 [英] Getting out of a potential deadlock

查看:75
本文介绍了摆脱潜在的僵局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了SEEM陷入僵局的情况.死锁听起来有点像:

I ran into what would SEEM to be a deadlock. Does a deadlock sound a little like:

  • 无法关闭窗口
  • 没有IDE上的终止按钮就无法终止
  • 空白,什么也没有发生,根本没有异常或错误.

如果这些都是死锁中发生的事情,那么我大概已经解决了一半的问题.我有两个正在运行的线程:AWT-EventQueue-0frameThread.

if those are the things that happen in a deadlock, then I probably have half the problem solved already. I have two threads that I know of are running: AWT-EventQueue-0 and frameThread.

这使用的是我建立的自定义库,但尚未完全开发(您可以称其为alpha-beta阶段?).我决定用它来制作Pong游戏.实际上,我的导师为我分配了游戏.我将使用它的库.

This is using a custom library that I built and isn't fully developed yet (what you might call alpha-beta stage?). I decided to use it to make a Pong game. Actually my mentor assigned me the game. I'm just going to use my library with it.

我的库使用了Swing组件,我怀疑这与它有任何关系.

My library uses Swing components and I doubt that has anything to do with it.

我想指出,

当线程调用同步方法时,它将自动获取该方法对象的内在锁,并在该方法返回时释放该内在锁.即使该返回是由未捕获的异常引起的,也会释放该锁."

"When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception."

在执行此操作之前,我已经完成了一个同步块,以从我在程序中知道的唯一具有锁的线程中获取锁.失败的.因此,我使该方法同步,并且发生了上面列出的要点.

before doing what this says, I had done a synchronized block to acquire the lock from the only thread I know of in my program that could have the lock. Failed. So I made the method synchronized and, well, the bullet points listed above happened.

我的代码是

// Threads
static ThreadManager tm = new ThreadManager() {

    @Override
    protected void runFrameThread() {//ThreadManager has threads in it that you can start.
        while (true) {               //These are just the abstract inherited methods the
            Main.jpane.repaint();    // threads inside the manager call
        }
    }

    @Override
    protected void runMathThread() {
    }

    @Override
    protected void runIntenseMathThread() {
    }

};

// set frame rate
static {
    tm.setFPS(30L);
}

public synchronized void draw(Graphics g) {// main problem: synchronized method here.
    try {
        wait(hertz);
    } catch (InterruptedException e) {
        System.err.println("ERROR: " + e.getLocalizedMessage());
        e.printStackTrace();
    }
    g.setColor(rgb);
    g.fillRect(this.x, this.y, width, height);
}

如果这没有帮助,您可以尝试浏览我的代码...

if that doesn't help, you can try looking through my code...

我的Pong游戏代码存储库

我最好的选择是我为延迟该方法所做的事情是错误的.我想要做的是以'x'hertz的设置速率为每个对象设置一个更新速率.如果它是返回类型方法(不是void),它会会更容易.

My best bet is its something wrong with what Im doing to delay the method. what I want to do is have an update rate for every object at a set rate of 'x' hertz. It would be easier if it was a return type method (not void).

推荐答案

您声明:

我的图书馆使用了Swing组件,我怀疑这与它有任何关系

My library uses Swing components and I doubt that has anything to do with it

我担心您可能错了.您似乎在用while循环完全阻塞了Swing事件分配线程(EDT),并且由于该线程负责所有Swing图形和用户交互,因此将有效地冻结GUI.

I fear that you may be very wrong. You appear to be completely blocking the Swing event dispatch thread (the EDT) with your while loop, and since this thread is responsible for all Swing graphics and user interaction, this will effectively freeze your GUI.

  • 请使用Swing计时器,而不是会阻塞EDT的while (true)循环.
  • 请勿暂停您的图形绘制,因为这会使您的程序似乎响应速度较慢.
  • 不要从绘画方法中调用同步.
  • 请勿在诸如paintComponent之类的绘画方法中更改对象的状态(即,请勿从paintComponent中调用您的updateGame()方法).这是因为您永远无法完全控制是否调用此方法.响应操作系统要求清理脏区的请求,JVM可以将其调出您的控制范围,并且如果重画请求不断堆积,JVM可能会忽略您的重画请求.
  • Rather than a while (true) loop that will block the EDT, use a Swing Timer instead.
  • Don't pause your graphics drawing as this will make your program seem poorly responsive.
  • Don't call synchronize from within a painting method.
  • Don't change the state of your objects from within a painting method such as paintComponent (i.e., don't call your updateGame() method from within paintComponent). This is because you never have full control over whether or even if this method will be called. It can be called out of your control by the JVM in response to a request by the OS to clean a dirty region, and the JVM may ignore your request for a repaint if repaint requests are stacking up.

这篇关于摆脱潜在的僵局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆