布尔值未在线程中更改 [英] Boolean not changing in thread

查看:118
本文介绍了布尔值未在线程中更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class MPClient and MultiplayerMatch. MultiplayerMatch, in his constructor, creates a MPClient runnable thread.

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

To avoid data overflow, I have a boolean named "moved" in MultiplayerMatch that changes to true when the player is moving.

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

In the updateMatch method, if there's any player movement, "moved" changes to true, which allow MPClient to enter an if statment (inside while). This way MPClient only sends data to the server when something changes on the game.

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

Neverthless, when the flag is true, in MPClient that change is not registed! MPClient still "thinks" moved equals false, even after that flag changed in MultiplayerMatch, and as a consequence, nothing is sent to the server...

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

After a few tests, I noticed that if I run it in Debug Mode, since I have some breakpoints, that change is registered and everything works great! Why is the boolean change only "seen" though Debug Mode? Does it have something to do with the app "running speed", since there are breakpoints?

这只是代码的重要部分:

Here's only the important part of the code:

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);
            }
        }
    }));
}
}

MultiplayerMatch:

MultiplayerMatch:

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

This is because it is reading a cached value of match.moved variable instead of the latest. To avoid this, declare the variable as volatile

public volatile boolean moved;

此处

这篇关于布尔值未在线程中更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆