我正在尝试用Swing编写一个多线程程序。本质上该程序的工作原理是,当它运行时,它将有一个机器人(在屏幕截图中用圆圈表示),它在一个字段中徘徊。这个机器人应该由它自己的线程控制。该程序有一个按钮" Launch Robot"这将在场上创造另一个机器人(最多10个)。现在我有程序的基础知识,但它都在一个线程下运行。我可以根据需要启动尽可能多的机器人,但它们都在一个线程下运行。但是每当我点击"启动Robot"创建一个独立的线程并控制该机器人。这就是该程序现在的样子:
由于它有点长,我不会发布整个节目。但是启动和更新机器人的方法(目前仅控制场上的一个机器人)如下:
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
的基础知识,但由于我还没有完成任何多线程,我不知道如何使多个线程工作并由一个线程更新(更新控制的机器人的位置)通过线程)。
编辑:只是为了表明我的观点,这是我正在研究的项目。它不是关于多线程在这种情况下是否有意义。
答案 0 :(得分:2)
创建包含RobotModel
的{{1}}并定义其互动。在SwingWorker
的Collection<Robot>
实现中迭代模型。在有意义的事件发生时调用doInBackground()
,并通过查询模型publish()
更新process()
视图。正如here所讨论的那样,模型中应该没有绘图,视图中没有交互逻辑。单个工作人员应该足够适合中等复杂的模型,但您可以按照here所示同步多个工作人员。
答案 1 :(得分:1)
实现这一目标的一个好方法是使用ScheduledThreadPoolExecutor 通过以下方式实例化线程池:
namespace RockPaperScissors
{
enum GameAction
{
Rock,
Paper,
Scissors
}
abstract class Player
{
public abstract GameAction Act();
}
class PlayerRock : Player
{
public override GameAction Act()
{
return GameAction.Rock;
}
}
要创建新的机器人线程,请使用:
ScheduledThreadPoolExecutor threadsPool = new ScheduledThreadPoolExecutor(size);
这样,每次调用都会实例化一个新的Thread 您可以通过“size”参数设置允许线程总数的限制 您还可以在每个线程完成后使用以下内容传递结果:
threadsPool.submit(new Runnable() {
@Override
public void run() {
launchRobot();
}
});
如果您想要更少的细节,可以使用以下便利API让Java为您完成工作:
public <T> Future<T> submit(Runnable task, T result)
(无界线程池,具有自动线程回收)或:
Executors.newCachedThreadPool()
(固定大小的线程池)
记住我们,执行官。记住今天在这里做了什么。也许Adun会监视你
答案 2 :(得分:1)
这个机器人应该由它自己的线程控制。
为什么?
IMO,描述任何线程的最重要方式是说明等待的内容。在Internet服务器中,接受线程等待来自新客户端的传入连接,客户端线程等待来自单个客户端的其他命令。在执行大规模并行计算的程序中,工作线程等待执行任务。在GUI程序中,事件调度线程等待键盘和鼠标事件。等等。
您的机器人线程会等待什么?
如果它等待时间过去(即,如果它调用Thread.sleep()),那么你的GUI框架可能已经有一个计时器线程这样做,你可能想要考虑使用它。 (在Swing中,您将使用javax.swing.Timer
类提交新的定时任务。)