使用 Swing 的多线程
Multi-threading with Swing
我正在尝试用 Swing 编写一个多线程程序。从本质上讲,该程序的工作原理是,当它 运行 时,它将有一个机器人(在屏幕截图中用圆圈表示)在田野里四处游荡。这个机器人应该由它自己的线程控制。该程序有一个“启动机器人”按钮,可以在场地上创建另一个机器人(最多可以说 10 个)。现在我已经掌握了程序的基础知识,但所有 运行 都在一个线程下。我可以根据需要启动任意数量的机器人,但它们都 运行 在一个线程下。但我希望每当我单击“启动机器人”时,都会创建一个独立的线程并控制该机器人。这是程序现在的样子:
程序的UML图如下:
因为有点长我不会post整个程序。但是启动和更新机器人(目前只控制场上一台机器人)的方法如下:
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
的基础知识,但由于我没有做过任何多线程,所以我不知道如何让多个线程工作并由一个线程更新(update position of robots that are controlled by threads ).
编辑:为了说明我的观点,这是我正在从事的一个项目。这与多线程在这种情况下是否有意义无关。
创建一个包含 Collection<Robot>
的 RobotModel
并定义它们的交互。在 SwingWorker
. Invoke publish()
as meaningful events arise, and process()
updates to the RobotWorld
view by querying the model. 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.
的 doInBackground()
实现中迭代模型
实现此目的的一个好选择是使用 ScheduledThreadPoolExecutor.
通过以下方式实例化线程池:
ScheduledThreadPoolExecutor threadsPool = new ScheduledThreadPoolExecutor(size);
要创建新的机器人线程,请使用:
threadsPool.submit(new Runnable() {
@Override
public void run() {
launchRobot();
}
});
这样,每次调用都会实例化一个新线程。
您可以通过“大小”参数设置允许的线程总数限制。
您还可以在每个线程完成后传递结果:
public <T> Future<T> submit(Runnable task, T result)
如果你想要更少的细节,你可以让 Java 为你做这些工作 API:
Executors.newCachedThreadPool()
(无界线程池,线程自动回收)或:
Executors.newFixedThreadPool(int)
(固定大小的线程池)
记住我们,执行官。记住今天在这里做了什么。愿亚顿守护你
This robot should be controlled by a thread of it's own.
为什么?
IMO,描述任何线程的最重要方式是说明它 等待 的目的。在 Internet 服务器中,接受线程 等待来自新客户端的传入连接,而 客户端线程 等待来自单个客户端的其他命令。在执行大量并行计算的程序中,工作线程 等待执行任务。在 GUI 程序中,事件调度线程 等待键盘和鼠标事件。等等等等
您的机器人线程将等待什么?
如果它等待时间过去(即,如果它调用 Thread.sleep()),那么您的 GUI 框架可能已经有一个 计时器线程 来执行此操作,您可能要考虑使用它。 (在 Swing 中,您将使用 javax.swing.Timer
class 来提交新的定时任务。)
我正在尝试用 Swing 编写一个多线程程序。从本质上讲,该程序的工作原理是,当它 运行 时,它将有一个机器人(在屏幕截图中用圆圈表示)在田野里四处游荡。这个机器人应该由它自己的线程控制。该程序有一个“启动机器人”按钮,可以在场地上创建另一个机器人(最多可以说 10 个)。现在我已经掌握了程序的基础知识,但所有 运行 都在一个线程下。我可以根据需要启动任意数量的机器人,但它们都 运行 在一个线程下。但我希望每当我单击“启动机器人”时,都会创建一个独立的线程并控制该机器人。这是程序现在的样子:
程序的UML图如下:
因为有点长我不会post整个程序。但是启动和更新机器人(目前只控制场上一台机器人)的方法如下:
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
的基础知识,但由于我没有做过任何多线程,所以我不知道如何让多个线程工作并由一个线程更新(update position of robots that are controlled by threads ).
编辑:为了说明我的观点,这是我正在从事的一个项目。这与多线程在这种情况下是否有意义无关。
创建一个包含 Collection<Robot>
的 RobotModel
并定义它们的交互。在 SwingWorker
. Invoke publish()
as meaningful events arise, and process()
updates to the RobotWorld
view by querying the model. 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.
doInBackground()
实现中迭代模型
实现此目的的一个好选择是使用 ScheduledThreadPoolExecutor.
通过以下方式实例化线程池:
ScheduledThreadPoolExecutor threadsPool = new ScheduledThreadPoolExecutor(size);
要创建新的机器人线程,请使用:
threadsPool.submit(new Runnable() {
@Override
public void run() {
launchRobot();
}
});
这样,每次调用都会实例化一个新线程。
您可以通过“大小”参数设置允许的线程总数限制。
您还可以在每个线程完成后传递结果:
public <T> Future<T> submit(Runnable task, T result)
如果你想要更少的细节,你可以让 Java 为你做这些工作 API:
Executors.newCachedThreadPool()
(无界线程池,线程自动回收)或:
Executors.newFixedThreadPool(int)
(固定大小的线程池)
记住我们,执行官。记住今天在这里做了什么。愿亚顿守护你
This robot should be controlled by a thread of it's own.
为什么?
IMO,描述任何线程的最重要方式是说明它 等待 的目的。在 Internet 服务器中,接受线程 等待来自新客户端的传入连接,而 客户端线程 等待来自单个客户端的其他命令。在执行大量并行计算的程序中,工作线程 等待执行任务。在 GUI 程序中,事件调度线程 等待键盘和鼠标事件。等等等等
您的机器人线程将等待什么?
如果它等待时间过去(即,如果它调用 Thread.sleep()),那么您的 GUI 框架可能已经有一个 计时器线程 来执行此操作,您可能要考虑使用它。 (在 Swing 中,您将使用 javax.swing.Timer
class 来提交新的定时任务。)