一 JPanel 上绘制 10 条线程

3
我在学习Java中的线程时遇到了一些问题。目标是创建一个模拟,展示兔子在某种地图上逃离狼群的场景。每只狼和每只兔子都应该是一个线程。所以我在Test类的主方法中创建了一个GUI,并创建了一个实现了Runnable接口的新类。我认为这很容易和合乎逻辑。但现在,我该如何从这些线程中调用AddRabbit方法?因为每个线程都需要执行以下操作:
  1. 更改其属性,例如在地图上的位置
  2. 检查地图上其他线程的位置
  3. 在面板上绘制自己
但是怎样做呢?

你正在使用错误的工具来完成你的工作。当你想要进行并发执行时,应该使用线程,这并不意味着并行(通常是天真地假设),而是没有任何时间关系。另一方面,模拟通常意味着所有的参与者/组件都应该相互关联地执行它们的活动,这正好相反。你应该使用普通对象和一个Timer - Holger
2个回答

5

直接使用多个线程更新Swing组件是不允许的——Swing不是线程安全的。它只有一个事件队列来处理,因此如果你必须在已有的线程中更新JComponent,则需要使用以下代码:

//You are currently in a separate thread that's calculating your rabbit positions
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        //Put in code to modify your Swing elements
    }
});

因此,每当您需要更新GUI时,您可以使用SwingUtilities.invokeLater方法将Runnable实例传递到Swing事件队列中,在其自己的线程中处理。


回答很好,简单易懂,但是你没有理解问题或者我表述不够清楚。目标是使用几个线程操作一个对象。我需要在哪里创建这个对象?在测试类中吗?目前我已经在测试类中创建了它,但我感觉这不是一个好主意,而且我也不知道为什么^^无论如何,谢谢! - ŁukaszG
这是正确的方法;完整的示例请参见此处 - trashgod

4

对于从多个线程更新GUI,建议使用continuation这里有相关建议。但是正确同步访问共享数据可能会很困难。

或者,可以使用javax.swing.Timer定期更新管理狼和兔子属性的模型。一个相关的在网格上移动对象的例子在这里被考虑。为了更大的灵活性,使用Model–View–Controller模式,这里进行了说明。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接