【问题标题】:While loops and...threads?While 循环和...线程?
【发布时间】:2015-06-14 07:36:22
【问题描述】:

我创建了一个网络游戏。我遇到了(看似)无法解释的错误的问题。请注意,卡片是通过鼠标单击添加到 ArrayList 中的,并且此类在其自己的线程上运行。

private void waitForAction(){

    tb.report("Waiting for user to make a move...");
    selectedCards = new ArrayList<Card>();
    while(selectedCards.size() < 2){
        if(selectedCards.size() == 2)//Wtf is going on here...?
            tb.report("This loop is (not) broken.");
        else
            tb.report("Looping..");
    };
    tb.report("This player has selected 2 cards.");
}

当我删除 else 语句时,循环永远不会退出,print(report()) 方法向我证明了这一点。我在早期的开发中遇到了同样的问题,但是通过添加 if-else 语句的 if 部分来纠正它。老实说,我感到困惑,逻辑推理告诉我 JVM 没有检查条件,因为线程没有运行,但是在整个程序中我只调用过一次 Thread 的 start() ,否则它不会被我的代码触及。任何更明智的鞋底的意见将不胜感激。

【问题讨论】:

  • 请发布您的输出!
  • 另一个线程发生了什么?到目前为止,我只看到一个线程中 selectedCards 从未发生变异,因此循环永远运行也就不足为奇了。
  • 我怀疑另一个线程正在将卡片添加到不同的 ArrayList 中,所以这个没有被修改。
  • 您可能没有在两次运行之间完全重新编译您的代码。
  • @Rong - 目前我已经获得了超过 2000 行代码,其中大部分是图形输出,我同意如果没有更多就很难解决,但通常这是对我们隐藏的显而易见的事情。

标签: java multithreading loops if-statement


【解决方案1】:

如果没有更多信息,很难准确地告诉您出了什么问题。但是,我强烈建议您使用更多基于事件的模型来编写服务器。特别是考虑到它是一款纸牌游戏,所以我猜它是回合制而非实时的。

不要使用基于循环的方法,试试这个:

  1. 服务器保存游戏当前状态的模型。
  2. 客户端向服务器发送消息。其中一种信息可能是“玩牌 XYZ”
  3. 服务器处理消息并相应地更新模型。如果用户打出一张牌,它可能会从该人的手上移除该牌。它可能会根据卡片的效果改变一些其他状态。收到消息时处理所有逻辑。
  4. 将状态更改发送给所有客户端,以便它们看到与服务器状态一致的视图。

【讨论】:

  • 感谢您的尝试!我同意,不幸的是,如果不显示所有 2000 多行,就很难显示更多内容......总是问题,对吧?我会考虑基于事件的结构,但是当人类用户选择两张牌时,游戏必须等待,因为每张牌都被选中,客户端从服务器请求牌的价值。
  • 游戏永远不需要等待。如果是基于事件的,那么用户点击卡片就是触发逻辑的事件。
【解决方案2】:

你有多线程环境。 ArrayList 不是一个线程安全的集合——它不保证在其他线程上的可见性。这意味着您的等待线程永远不会看到集合中的更改。

尝试使用 java.util.concurrency 的一些集合。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 2010-09-28
    • 2016-04-11
    • 2013-01-12
    • 2012-10-28
    • 2011-06-12
    • 2018-11-29
    相关资源
    最近更新 更多