0
public Boolean performAction(AppleCollectorAgent agent, data.ActionType action)
{
    if(agent != null && action != null)
    {
        actions.put(agent, action);
    }
    else
    {
        System.out.println("GRID:  "+agent+" performs "+action+" TID: "+Thread.currentThread().getId()+". Time: "+ new Date().getTime());
        System.out.println("Either agent or action was null: "+agent+" - "+action);
    }
}

被称为

ActionType ac = ActionType.ApplePickup;
System.out.println("AGENT: "+myAgent+" going to perform "+ac+" TID: "+Thread.currentThread().getId()+". Time: "+ new Date().getTime());
success = GridWorld.get().performAction((AppleCollectorAgent)myAgent, ac);

这适用于枚举 Action 的其他值,但对于值 Action.PickupApple,actions.put 会抛出 NullPointerException。当我放置一些 println 来显示参数的值时,它变得更加奇怪。在调用之前,ac 被打印为 PickApple,而在 performAction 中,action 被打印为 null:

GRID:  Agents.GreedyAgent@1a42792 performs null TID: 29. Time: 1296317211796
Either agent or action was null: Agents.GreedyAgent@1a42792 - null
AGENT: Agents.GreedyAgent@1a42792 going to perform ApplePickup TID: 29. Time: 1296317211796

那么,在performAction中action怎么会变成null呢?

背景的一些解释:对于多代理系统的课程,我必须模拟一个网格世界,代理可以在其中四处走动并捡起苹果。在每个模拟步骤中,每个代理都可以执行一个动作。动作类型存储在枚举 data.Action 中。actions 是一个 ConcurrentHashMap,每个 agent 都存储了他想要做的 Action。当所有代理都这样做时,gridworld 会处理所有这些并返回一个布尔值,指示操作成功。每个代理都有自己的线程,网格世界也是如此。再往下 performAction() 有一些同步机制。我一开始以为是多线程出了问题,但我认为我可以放心,这不是问题所在。action 为空,这就是问题所在。

4

1 回答 1

1

从评论中推断,我会说它performAction被调用了两次。特别是如果它似乎“有时”有效。一次操作为 null,一次操作为 PickApple。

如果是这种情况,您可以使用Thread.currentThread().getStackTrace()来确定调用方法的位置。

于 2011-01-29T16:11:07.653 回答