调用后枚举变为空
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);
}
}
对于枚举 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.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
那么,action在performAction中如何变成null呢?
对背景的一些解释: 对于多代理系统的课程,我必须模拟网格世界,其中代理可以四处走动并捡起苹果。在每个模拟步骤中,每个代理可以执行一个动作。操作类型存储在枚举 data.Action 中。 actions是一个ConcurrentHashMap,其中每个agent存储了他想做的Action。当所有代理都完成此操作后,网格世界会处理所有这些并报告返回一个布尔值,表明操作成功。 每个代理都有自己的线程,网格世界也是如此。在performAction()下面有一些同步机制。 我首先认为这将是多线程出了问题,但我认为我可以放心这不是问题所在。操作为空,这就是问题所在。
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);
}
}
is called by
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);
This works fine for other values of the enum Action, but for the value Action.PickupApple, actions.put throws a NullPointerException.
When I put some println's around to display the values for the arguments, it gets even weirder. Before the call, ac is printed as PickApple, and in performAction, action gets printed as 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
So, how can action become null in performAction?
Some explanation on the background:
for a course on multi-agent systems, I have to make a simulation of a gridworld, in which agents can wander around and pick up apples. In each simulation step, each agent can perform one action. The actions types are stored in the enum data.Action. actions is a ConcurrentHashMap, in which each agent stores the Action he wants to do. When all agents have done that, the gridworld processes all that and reports back a Boolean, indicating the success of the action.
Each agent has its own thread, as does the gridworld. Further down performAction() there are some syncing mechanisms.
I first thought it would be the multithreading that went all wrong, but I think I can safely that that is not the problem. action is null, that is the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从评论中推断,我想说
performAction
被调用了两次。特别是如果它似乎“有时”有效。一次将操作设置为 null,一次将操作设置为 PickApple。如果是这种情况,您可以使用 Thread.currentThread().getStackTrace() 来确定该方法是从哪里调用的。
Deduced from the comments, I'd say that
performAction
is being called twice. Especially if it seems to "sometimes" work. Once with action as null, and once with action as PickApple.If this is the case, you can use
Thread.currentThread().getStackTrace()
to work out from where the method is called.