You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#多线程模拟大富翁游戏出现玩家位置异常及崩溃问题

问题原因分析

你的核心问题是多线程之间共享了同一个Player实例,导致并发修改可变状态时出现竞态条件,最终破坏了Player的Position数据。

具体代码问题

在PrepareGame方法中,你创建了一个全局的players列表,然后将这个列表直接传递给每一个新创建的Game对象。这意味着所有线程中的Game.Players指向的都是同一批Player实例。当多个线程同时调用p.Move()修改同一个Player的Position时,由于Position的更新操作不是原子性的,会出现以下典型的竞态场景:

  1. 线程A读取Player的当前Position值(比如5)
  2. 线程B同时读取同一个Player的Position值(还是5)
  3. 线程A计算新位置(5+3=8)并写入
  4. 线程B计算新位置(5+4=9)并写入
    此时线程A的更新被覆盖,更严重的是如果涉及减法操作(比如入狱扣位置),交错的读写可能直接导致Position变为负数。

为什么Thread.Sleep()只能缓解不能解决

添加Thread.Sleep()只是降低了线程间操作重叠的概率,但并没有从根本上阻止并发访问。竞态条件是随机发生的,只要共享可变状态的问题存在,就总会有概率出现数据损坏。

修复方向

每个游戏模拟都应该拥有独立的Player实例,避免跨线程共享。修改创建Game的代码,为每个游戏克隆一份Player对象:

// 替换原Game构造调用,为每个游戏创建新的Player实例
var gamePlayers = players.Select(p => new Player(p.Name)).ToList();
GameLoop(new Game(i, board, gamePlayers));

这样每个线程的游戏都会操作自己的Player对象,线程间不会互相干扰。

另外,如果你的Board类也包含可变状态(比如地块的所有权、建筑等级等),同样需要为每个游戏创建独立的Board实例,避免跨游戏共享状态。

内容的提问来源于stack exchange,提问作者Titus Tesche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:37:04