当前位置:  开发笔记 > 编程语言 > 正文

线程问题

如何解决《线程问题》经验,为你挑选了1个好方法。

我正在使用Java.

我有这个线程,代理,探索一个房间来确定它的大小,并清理它,如果它是脏的.然后我有了界面,它在探索环境时绘制代理.Agent是Thread的子类,Java负责管理线程.我所做的就是创建线程并说出object.start().

这在正常情况下非常有效.但是,在此期间启用菜单,这意味着用户可以在代理正在探索时弄乱房间.这不应该发生.

因此,一旦用户单击告诉代理清理房间的选项,我想禁用所有菜单.除非它不能正常工作.这是问题所在:

...
public void ActionPerformed(ActionEvent e)
{
    //disable the menus with setEnabled(false);
    agent.start();
    //enable the menus with setEnabled(true);
}

问题是在代理程序线程执行其功能之前启用了菜单.我想过使用Thread.join() - 这可以保证启用菜单的代码只在代理程序线程结束后执行.但是,如果我使用Thread.join(),代理移动时接口不会自动更新,因为它正在等待代理完成!

我已经考虑过从代理中禁用接口,然后在代理完成后启用它,但我不确定它是否会起作用,这里最大的问题是代理不应该乱用菜单.

所以,总结一下,我需要一个执行更新接口的线程/绘制代理移动,但该线程不能与启用菜单相同.目前似乎有一个线程同时执行这两个操作.假设这是可能的而不是太复杂.



1> Zach Scriven..:

我已经考虑过从代理中禁用接口,然后在代理完成后启用它,但我不确定它是否会起作用,这里最大的问题是代理不应该乱用菜单.

您可以使代理程序调用GUI类中的一个方法,该方法在完成后重新启用菜单.当然,该方法将在EDT上调用适当的Swing方法.

class Agent extends Thread
{
    @override
    public void run()
    {
       // run around the room

       // finally done
       gui.agentIsDone();
    }
}

class GUI extends JFrame
{
    ...

    void agentIsDone()
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @override 
            public void run()
            {
                menus.setEnabled(true);
            }
        });
    } 
}

如果多个代理可以同时运行,则在重新启用菜单之前,您需要检查是否所有代理都已完成.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有