简体   繁体   English

如果没有println,Java代码将无法正常工作

[英]Java code doesn't work without a println

Here is my code: 这是我的代码:

while(monster.curHp > 0)
{
    System.out.println("");
    if(battle.pressedButton)
    {
        text = Player.name + ": " + Player.curHitPoints + "     " + monster.name + ": " + monster.curHp;
        battle = new GUIForBattle(text,Player,monster);
    }
}

The weird thing is that if I have that println line in the while loop the code will work normally and when the button is pressed we will update text to have the current status and we will redraw the GUI using the GUIForBattle class, however if I don't have that println it wont redraw. 奇怪的是,如果我在while循环中有该println行,则代码将正常工作,并且当按下按钮时,我们会将文本更新为当前状态,并使用GUIForBattle类重绘GUI,但是如果我不这样做,没有那个println它不会重绘。 Any advice? 有什么建议吗? Thank you! 谢谢!

Here is the GUIForBattle for more context 这是GUIForBattle的更多上下文

public class GUIForBattle extends JFrame {
boolean pressedButton = false;
public GUIForBattle(String words, player PlayerOne, Monster monster)
{
    JFrame frame = new JFrame(); //frame that holds everything
    JPanel Panel = new JPanel(new GridLayout(5,5)); //panel where things get added
    JLabel text = new JLabel(words); // text label
    JButton attack = new JButton("Attack"); //makes a button used to attack
    //adding what pressing the attack button would do 
    attack.addActionListener(
            new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    int attackAmount = PlayerOne.weaponEquipped.att;
                    monster.curHp = monster.curHp - attackAmount;
                    pressedButton = true;
                }
            }
            );
    JButton Item = new JButton("Item"); // makes a button used to use items
    Item.addActionListener(
            new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    //we need to make a item interface
                }
            });
    Panel.add(text); //adds the text to the panel
    Panel.add(attack);
    Panel.add(Item);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(800, 800); //setting size of frame
    frame.add(Panel); //adding the panel to frame
    frame.setVisible(true); //making the frame visible
}

} }

Your code is inherently multi-threaded; 您的代码本质上是多线程的; one thread is running through that little while loop; 一个线程正在运行该小while循环; the other is the swing application thread that will be handling your swing event handlers. 另一个是将处理您的swing事件处理程序的swing应用程序线程。

If you use shared variables like this (both threads access pressedButton ) you need to make sure that variable is synchronized between threads. 如果您使用这样的共享变量(两个线程都访问pressedButton ),则需要确保该变量在线程之间是同步的。 There are several ways of handling this, but an easy way for this particular problem would be to make the variable volatile. 有几种处理方法,但是解决此特定问题的简单方法是使变量易变。

If the variable is not synchronized in any way, there is no guarantee by the JVM as to when one thread will 'see' the changes made to it by the other. 如果该变量没有以任何方式同步,则JVM无法保证一个线程何时“看到”另一线程对其所做的更改。 And typically, if you keep one thread occupied like you're doing here (this while loop is called a busy wait) it will never take the time to synchronize, and you'll never see the updates. 通常,如果您像在此处那样占用一个线程(此while循环称为繁忙等待),它将永远不会花费时间进行同步,也永远不会看到更新。

The println is an IO operation, meaning at some point your thread will be waiting for IO to complete. println是一项IO操作,这意味着在某些时候您的线程将等待IO完成。 Most likely this causes the JVM to synchronize the variables, which is why you notice this difference. 这很可能导致JVM同步变量,这就是为什么您会注意到这种差异。

In any case, relying on this without thinking about synchronization can be considered a bug. 无论如何,在不考虑同步的情况下依靠它可以被认为是一个错误。

Java threads and memory handling are a complex subject, and not something I would advise for beginners to jump in to; Java线程和内存处理是一个复杂的主题,对于初学者,我不建议这样做。 it could be overwhelming. 这可能是压倒性的。 Just try to avoid sharing memory between threads for now. 暂时尝试避免在线程之间共享内存。 For the moment, just run your logic in your swing application code (it's not ideal, but for some beginner code it's probably a good starting point). 目前,只需在您的swing应用程序代码中运行您的逻辑即可(这并不理想,但是对于某些初学者来说,这可能是一个不错的起点)。

When you feel ready for it, read up on the memory model and what it implies for multi-threading . 当您准备就绪时,请阅读内存模型及其对多线程的含义

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM