繁体   English   中英

带Swing的多线程

[英]Multi-threading with Swing

我正在尝试使用Swing编写多线程程序。 实质上,程序的工作方式是运行时将有一个机器人(在屏幕快照中以圆圈表示),该机器人在一个字段中四处寻找。 该机器人应该由自己的线程控制。 该程序有一个“启动机器人”按钮,它将在现场创建另一个机器人(最多说10个)。 现在,我已经有了该程序的基础知识,但是所有程序都在一个线程下运行。 我可以启动任意数量的机器人,但它们都在单个线程下运行。 但是我希望每当我单击“启动机器人”时,都会创建一个独立线程并控制该机器人。 该程序现在的外观如下: 在此处输入图片说明

该程序的UML图如下: 在此处输入图片说明

由于时间太长,我不会发布整个程序。 但是,启动和更新机器人的方法(当前仅在现场控制一个机器人)如下:

    public void gameStart(){
    Thread gameThread = new Thread(){
        public void run(){
            while(true){
                //execute one time step for the game
                gameUpdate();

                //refresh screen
                repaint();

                //give other threads time
                try{
                    Thread.sleep(1000/UPDATE_RATE);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    };

    gameThread.start();
}

我的问题是在这种情况下如何实现多线程? 我知道SwingWorker的基础知识,但是由于我还没有做任何多线程处理,因此我不知道如何使多个线程工作并由一个线程进行更新(由线程控制的机器人的更新位置)。

编辑:为了说明我的意思,这是我正在从事的项目。 在这种情况下,多线程是否有意义并不重要。

创建一个包含Collection<Robot>RobotModel并定义它们的交互。 SwingWorkerdoInBackground()实现中迭代该模型。 在有意义的事件发生时调用publish() ,然后通过查询模型来对RobotWorld视图进行process()更新。 如所讨论的在这里 ,应该有在模型中没有图并在视图中没有交互逻辑。 单个工作应该足够一个中等复杂的模型,但可以如图同步多个工人在这里

实现此目的的一个不错的选择是使用ScheduledThreadPoolExecutor
通过以下方式实例化线程池:

ScheduledThreadPoolExecutor threadsPool = new ScheduledThreadPoolExecutor(size);

要创建新的机器人线程,请使用:

    threadsPool.submit(new Runnable() {
        @Override
        public void run() {
            launchRobot();
        }
    });

这样,每次调用都会实例化一个新的线程。
您可以通过“ size”参数设置允许的线程总数的限制。
您还可以在每个线程完成之后使用以下方法传递结果:

public <T> Future<T> submit(Runnable task, T result) 

如果您想减少细节,可以让Java使用以下便捷API为您完成工作:
Executors.newCachedThreadPool() (无边界线程池,具有自动线程回收)或:
Executors.newFixedThreadPool(int) (固定大小的线程池)

记住我们,执行官。 记住今天在这里做了什么。 愿阿顿看着你

该机器人应该由自己的线程控制。

为什么?

IMO,描述任何线程的最重要方法是说它等待什么。 在Internet服务器中, 接受线程等待来自新客户端的传入连接,而客户端线程等待来自单个客户端的其他命令。 在执行大量并行计算的程序中, 工作线程等待执行任务。 在GUI程序中, 事件分发线程等待键盘和鼠标事件。 等等

您的机器人线程会等待什么?

如果它等待时间过去(即,如果它调用Thread.sleep()),则您的GUI框架可能已经具有执行此操作的计时器线程 ,您可能要考虑使用它。 (在Swing中,您将使用javax.swing.Timer类提交新的定时任务。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM