当前位置: 首页 > 面试题库 >

布尔值未在线程中更改

钮善
2023-03-14
问题内容

我有一个MPClient和MultiplayerMatch类。MultiplayerMatch在其构造函数中创建一个MPClient可运行线程。

为了避免数据溢出,我在MultiplayerMatch中有一个名为“ moved”的布尔值,当播放器移动时,它会变为true。

在updateMatch方法中,如果有任何播放器移动,则“
moved”变为true,这允许MPClient输入if语句(在while内)。这样,MPClient仅在游戏发生更改时才将数据发送到服务器。

但是,当该标志为true时,则不会在MPClient中注册该更改!即使在MultiplayerMatch中更改了该标志,MPClient仍然“认为”移动等于假,结果没有任何内容发送到服务器…

经过几次测试后,我注意到如果以调试模式运行它,因为我有一些断点,则将记录该更改,并且一切正常!为什么通过调试模式只能“看到”布尔更改?由于存在断点,它是否与应用程序的“运行速度”有关?

这只是代码的重要部分:

MPClient:

public class MPClient {
static final int TIME_OUT = 5000;
Client client;
MultiPlayMatch match;

public MPClient(String name, int team, MultiPlayMatch match) {
    this.match = match;
    client = new Client();
    client.start();

    Network.registerPackets(client);
    addListeners();

    try {
        client.connect(TIME_OUT, "127.0.0.1", Network.PORT);
    } catch (IOException e) {
        e.printStackTrace();
        client.stop();
    }

    /*this comment is just to show that here is the place where the login information is sent to the server, instead of showing all the code*/

    PlayerInfo playerInfo = new PlayerInfo();
    Network.UpdatePlayer updatePlayer = new Network.UpdatePlayer();
    updatePlayer.name = name;
    updatePlayer.team = team;

    while(true) {
        if(match.moved) {       //--> this is the variable that is always false
            playerInfo.x = match.getClientPlayerX(team);
            playerInfo.y = match.getClientPlayerY(team);

            updatePlayer.x = playerInfo.x;
            updatePlayer.y = playerInfo.y;
            client.sendTCP(updatePlayer);
            match.moved = false;
        }
    }

}

private void addListeners() {
    client.addListener(new Listener.ThreadedListener(new Listener() {
        @Override
        public void received(Connection connection, Object object) {
            if(object instanceof Network.UpdatePlayer) {
                Network.UpdatePlayer updatePlayer = (Network.UpdatePlayer) object;
                match.setPlayerPosition(updatePlayer.x, updatePlayer.y, updatePlayer.name, updatePlayer.team);
            }
        }
    }));
}
}

多人比赛:

public class MultiPlayMatch extends Match {

public boolean moved;

public MultiPlayMatch(){
    super(0);

    Random r = new Random();
    int aux = r.nextInt(2);
    aux = 0;
    if(aux == 0){
        homeTeam = new Team("Benfica", Team.TeamState.Attacking, w);
        visitorTeam = new Team("Porto", Team.TeamState.Defending, w);
    } else{
        homeTeam = new Team("Benfica", Team.TeamState.Defending, w);
        visitorTeam = new Team("Porto", Team.TeamState.Attacking, w);
    }
    //homeTeam.controlPlayer(0);

    numberOfPlayers = 0;
    moved = false;
}

@Override
public void updateMatch(float x, float y, Rain rain, float dt) {
    homeTeam.updateControlledPlayerOnline(x, y);

    rain.update();
    w.step(Constants.GAME_SIMULATION_SPEED, 6, 2);

    if(x != 0 || y != 0) moved = true;      //this is the place the variable is changed, but if it isn't in debug mode, MPClient thinks it's always false
}

public void setPlayerPosition(float x, float y, String name, int team) {
    if(team == 0)
        homeTeam.changePlayerPosition(x, y, name);
    else
        visitorTeam.changePlayerPosition(x, y, name);
}
}

问题答案:

这是因为它正在读取match.moved变量的缓存值,而不是最新值。为了避免这种情况,请将变量声明为volatile

public volatile boolean moved;

在这里阅读更多



 类似资料:
  • 我有一个学校作业,要做一个程序,结果要么正确,要么错误。这关系到一年是否是闰年。目前的问题是,我使用的是公共静态布尔值,而不是公共布尔值。这是我的代码: 现在int年是2000年,但是规则是这样的:闰年是一年,可以除以4,除非这一年是一个新世纪的开始(1700, 1800, 1900.....)。所以即使你可以把1900除以4,你也不能把它除以400,所以这是错误的。所以再一次问一个问题:我需要做

  • 问题内容: 哪种列类型最适合在MySQL数据库中使用布尔值?我用,但我的同事用。 问题答案: 这些数据类型是同义词。

  • 因此,我的任务是制作多个“动物”类,并在空白绘图面板上运行它们。每只动物都以特定的方式移动,当它们与不同的动物重叠时,“入侵”的动物获胜,而另一只动物被移走。我的老师告诉我使用一个布尔值,如果两个动物在相同的坐标上交叉,则返回true(动物死亡),而在所有其他情况下返回false。 我在动物类上设置了一个自动返回false的布尔方法“isSameLoc()”,但是我不知道当动物在主客户端类中重叠时

  • 问题内容: 我有一个线程,它等待布尔值更改,如下所示: 这不是我首选的方法,因为这会导致大量CPU消耗。 有什么方法可以阻止线程,直到布尔值更改其状态? 问题答案: 这不是我首选的方法,因为这会导致大量CPU消耗。 如果这实际上是您的工作代码,则只需保留该代码即可。每秒检查一次布尔值不会导致可测量的CPU负载。没有任何。 真正的问题是检查该值的线程可能由于缓存而没有看到任意长时间的更改。为了确保该

  • 在对XML文件应用转换时,我得到了这个错误(即,未定义有效的布尔值)。这里有一个奇怪的陷阱: *我的应用程序从一个文件位置读取500到800个XML文件(XML文件大小范围从几KB到10MB),然后对每个文件进行转换。最初一切都很顺利,但在一些执行之后,它会在错误下面抛出: productsfromloc_v3.xsl: forg0006第651行错误:在xsl:call-template nam

  • 到目前为止我们看到的类型都能表示很大范围的数据,整数多的是,而浮点数更多。相对而言,字符集的规模小的多。C++中还有一个类型表示的范围更小,即布尔类型,它只能表示true和false两个值。 虽然没提到过该类型,但我们前面几章中实际已经使用过布尔值了。if语句和while语句中的条件就是布尔表达式。比较操作符的结果也是布尔值。例如: if (x == 5) { // 进行某些处理 } ==操