简体   繁体   English

带Swing的多线程

[英]Multi-threading with Swing

I am trying to write a multi-thread program with Swing. 我正在尝试使用Swing编写多线程程序。 Essentially how the program works is that when it runs it will have a robot(represented by a circle in screenshot) that is wondering around in a field. 实质上,程序的工作方式是运行时将有一个机器人(在屏幕快照中以圆圈表示),该机器人在一个字段中四处寻找。 This robot should be controlled by a thread of it's own. 该机器人应该由自己的线程控制。 The program has a button "Launch Robot" that will create another robot on the field(upto a max of say 10). 该程序有一个“启动机器人”按钮,它将在现场创建另一个机器人(最多说10个)。 Right now I have the basics of the program, but it all runs under one thread. 现在,我已经有了该程序的基础知识,但是所有程序都在一个线程下运行。 I can launch as many robots as I want but they all run under a single thread. 我可以启动任意数量的机器人,但它们都在单个线程下运行。 But I want that whenever I click "launch Robot" an independent thread be created and control that robot. 但是我希望每当我单击“启动机器人”时,都会创建一个独立线程并控制该机器人。 This is how the program looks right now: 该程序现在的外观如下: 在此处输入图片说明

The UML diagram for the program is as following: 该程序的UML图如下: 在此处输入图片说明

Since its a bit long I won't post the whole program. 由于时间太长,我不会发布整个程序。 But the method that starts and updates the robots(currently controlling only one robot on the field) is as follows: 但是,启动和更新机器人的方法(当前仅在现场控制一个机器人)如下:

    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();
}

My question is how can I achieve multi-threading for such a scenario? 我的问题是在这种情况下如何实现多线程? I know the basics of SwingWorker , but since I haven't done any multi-threading, I have no idea on how to make several threads work and be updated by one thread(update position of robots that are controlled by threads). 我知道SwingWorker的基础知识,但是由于我还没有做任何多线程处理,因此我不知道如何使多个线程工作并由一个线程进行更新(由线程控制的机器人的更新位置)。

EDIT: Just to make my point, this is a project that I am working on. 编辑:为了说明我的意思,这是我正在从事的项目。 It's not about if multi-threading makes sense in this scenario or not. 在这种情况下,多线程是否有意义并不重要。

Create a RobotModel that contains a Collection<Robot> and defines their interaction. 创建一个包含Collection<Robot>RobotModel并定义它们的交互。 Iterate the model in the doInBackground() implementation of a SwingWorker . SwingWorkerdoInBackground()实现中迭代该模型。 Invoke publish() as meaningful events arise, and process() updates to the RobotWorld view by querying the model. 在有意义的事件发生时调用publish() ,然后通过查询模型来对RobotWorld视图进行process()更新。 As discussed here , there should be no drawing in the model and no interaction logic in the view. 如所讨论的在这里 ,应该有在模型中没有图并在视图中没有交互逻辑。 A single worker should suffice for a moderately complex model, but you can synchronize multiple workers as shown here . 单个工作应该足够一个中等复杂的模型,但可以如图同步多个工人在这里

A good option to achieve this is to use ScheduledThreadPoolExecutor . 实现此目的的一个不错的选择是使用ScheduledThreadPoolExecutor
Instantiate the thread pool via: 通过以下方式实例化线程池:

ScheduledThreadPoolExecutor threadsPool = new ScheduledThreadPoolExecutor(size);

To create a new Robot Thread, use: 要创建新的机器人线程,请使用:

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

This way, each invocation will instantiate a new Thread. 这样,每次调用都会实例化一个新的线程。
You can set the limit of the total number of allowed Thread via the "size" argument. 您可以通过“ size”参数设置允许的线程总数的限制。
You can also pass a result after each thread completes using: 您还可以在每个线程完成之后使用以下方法传递结果:

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

If you want less detail, you could let Java do the work for you with the following convenience API: 如果您想减少细节,可以让Java使用以下便捷API为您完成工作:
Executors.newCachedThreadPool() (unbounded thread pool, with automatic thread reclamation) or: Executors.newCachedThreadPool() (无边界线程池,具有自动线程回收)或:
Executors.newFixedThreadPool(int) (fixed size thread pool) Executors.newFixedThreadPool(int) (固定大小的线程池)

Remember us, Executor. 记住我们,执行官。 Remember what was done here today. 记住今天在这里做了什么。 And may Adun watch over you 愿阿顿看着你

This robot should be controlled by a thread of it's own. 该机器人应该由自己的线程控制。

Why? 为什么?

IMO, the most important way to describe any thread is to say what it waits for. IMO,描述任何线程的最重要方法是说它等待什么。 In an internet server, an accept thread waits for incoming connections from new clients, and a client thread waits for additional commands from a single client. 在Internet服务器中, 接受线程等待来自新客户端的传入连接,而客户端线程等待来自单个客户端的其他命令。 In a program that performs massive parallel computations, a worker thread waits for tasks to be performed. 在执行大量并行计算的程序中, 工作线程等待执行任务。 In a GUI program, the event dispatch thread waits for keyboard and mouse events. 在GUI程序中, 事件分发线程等待键盘和鼠标事件。 Etc., etc. 等等

What will your robot thread wait for? 您的机器人线程会等待什么?

If it waits for time to pass (ie, if it calls Thread.sleep()), then your GUI framework probably already has a timer thread that does that, and you might want to consider using it. 如果它等待时间过去(即,如果它调用Thread.sleep()),则您的GUI框架可能已经具有执行此操作的计时器线程 ,您可能要考虑使用它。 (In Swing, you would use the javax.swing.Timer class to submit new timed tasks.) (在Swing中,您将使用javax.swing.Timer类提交新的定时任务。)

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

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