Java 除非使用System.out.println或在调试时,否则不会执行If

Java 除非使用System.out.println或在调试时,否则不会执行If,java,swing,if-statement,while-loop,Java,Swing,If Statement,While Loop,我们正在用Java和Swing与学生一起开发一个模拟器。我们遇到的问题是,在Simulator.java中单击一个按钮后,私有静态布尔起始按钮的变量变为true。在此之后,“如果”应该开始工作,但事实并非如此 我的Brain.java中有以下代码块: public class Brain { // ========================================================== /* * This is the Part of P

我们正在用Java和Swing与学生一起开发一个模拟器。我们遇到的问题是,在
Simulator.java
中单击一个按钮后,
私有静态布尔起始按钮的变量变为true。在此之后,“如果”应该开始工作,但事实并非如此

我的Brain.java中有以下代码块:


public class Brain
{
    // ==========================================================

    /*
     * This is the Part of Port A
     */
    // Tris for Port A | ARRAY VALUE 0
    private static boolean[] port_A_Tris_Checkboxes = new boolean[8];

    // PINs | ARRAY VALUE 1
    private static boolean[] port_A_Pins_Checkboxes = new boolean[5];

    /*
     * This is the Part of Port B
     */
    // Tris for Port B | ARRAY VALUE 2
    private static boolean[] port_B_Tris_Checkboxes = new boolean[8];

    // PINs | ARRAY VALUE 3
    private static boolean[] port_B_Pins_Checkboxes = new boolean[8];

    // ==========================================================

    /*
     * This is the Part of the Watchdog
     */
    private static boolean watchdogCheckbox;

    // ==========================================================

    /*
     * This is the Part of the Reset Button
     */
    private static boolean resetButton;

    // ==========================================================

    /*
     * This is the Part of the Einzelschritt Button
     */
    private static boolean einzelschrittButton;

    // ==========================================================

    /*
     * This is the Part of the Start Button
     */
    private static boolean startButton = false;

    // ==========================================================

    /*
     * This is the Part of the Stop Button
     */
    private static boolean stopButton = false;

    // ==========================================================

    public static void main(String[] args)
    {
        // startet das GUI
        Simulator.main(args);
        while (true) {

            if ((startButton == true) && (stopButton == false)) {

                // Do one step of the program
                Steuerwerk.runCommand(Decoder.decode(Simulator.getProgramMemory()
                        .getProgramMemory()[ProgramCounter.getProgramCounter()]),
                        Simulator.getProgramMemory().getProgramMemory()[ProgramCounter
                                .getProgramCounter()]);
                System.out.println(W_Register.getArgument());

            } else if (getStart() && getStop()) {

                /*
                 * If program has already started and the stop button was pressed,
                 * stop the program
                 */
                setStart(false);
                setStop(false);

            } else if (getStop()) {

                // No reason to save stopping of program if it didn't even start yet
                setStop(false);

            } else if (getEinzelschritt()) {

                // Do one step of the program
                Steuerwerk.runCommand(Decoder.decode(Simulator.getProgramMemory()
                        .getProgramMemory()[ProgramCounter.getProgramCounter()]),
                        Simulator.getProgramMemory().getProgramMemory()[ProgramCounter
                                .getProgramCounter()]);
                System.out.println(W_Register.getArgument());
                setEinzelschritt(false);
            }
        }

    }

    // ==========================================================

    /**
     * 
     * @param index : Checkbox value, true if checkbox has been marked
     * @param whichArray : Value that say which ArrayIndex is checked in which
     *        Array
     * 
     *        Diese Methode wird die in der GUI aktivierten Checkboxen hier in
     *        der Programm Logik vermerken sodass diese dann für die weitere
     *        Abarbeitung nach User wunsch geschehen und mit berüchsichtigung der
     *        aktivierten Checkboxen des Users
     */
    public static void setChechboxesForTrisOrPinBoolean(int index,
            int whichArray)
    {
        switch (whichArray) {
        case 0: {
            port_A_Tris_Checkboxes[index] = !port_A_Tris_Checkboxes[index];
            break;
        }
        case 1: {
            port_A_Pins_Checkboxes[index] = !port_A_Pins_Checkboxes[index];
            break;
        }
        case 2: {
            port_B_Tris_Checkboxes[index] = !port_B_Tris_Checkboxes[index];
            break;
        }
        case 3: {
            port_B_Pins_Checkboxes[index] = !port_B_Pins_Checkboxes[index];
            break;
        }
        default:
            throw new IllegalArgumentException("Unexpected value: " + whichArray);
        }
    }

    // ==========================================================

    /**
     * Diese methode wird die Aktivierung der Watchog Checkbox berücksichtigen
     * und eben dann auch vermerken
     */
    public static void setCheckboxForWatchdog()
    {
        watchdogCheckbox = !watchdogCheckbox;
    }

    // ==========================================================

    /*
     * The Set Method for the Reset Button
     */
    public static void setReset(boolean value)
    {
        if (value == true) {
            resetButton = true;
        } else {
            resetButton = false;
        }
    }

    /*
     * Get Method for the Reset Button Value
     */
    public static boolean getReset()
    {
        return resetButton;
    }

    // ==========================================================

    /*
     * The Set Method for the Einzelschritt Button
     */
    public static void setEinzelschritt(boolean value)
    {
        if (value == true) {
            einzelschrittButton = true;
        } else {
            einzelschrittButton = false;
        }
    }

    /*
     * Get Method for the Einzelschritt Button Value
     */
    public static boolean getEinzelschritt()
    {
        return einzelschrittButton;
    }

    // ==========================================================

    /*
     * The Set Method for the Start Button
     */
    public static void setStart(boolean value)
    {
        if (value == true) {
            startButton = true;
        } else {
            startButton = false;
        }
    }

    /*
     * Get Method for the Start Button Value
     */
    public static boolean getStart()
    {
        return startButton;
    }

    // ==========================================================

    /*
     * The Set Method for the Stop Button
     */
    public static void setStop(boolean value)
    {
        if (value == true) {
            stopButton = true;
        } else {
            stopButton = false;
        }
    }

    /*
     * Get Method for the Stop Button Value
     */
    public static boolean getStop()
    {
        return stopButton;
    }

    // ==========================================================
}

另一部分是我的模拟器:

JButton btnStart = new JButton("START");
        btnStart.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e)
            {
                // TODO Auto-generated method stub
                System.out.println("Pressed");
                Brain.setStart(true);
            }
        });

有趣的是,只有在添加
System.out.println()
或调试时。。。它启动if。

如果您在多个线程中同时修改变量,那么它们需要是易变的,除非您使用其他同步过程来确保存在读取障碍

大多数Swing代码将在事件分派线程上运行,该线程与主线程(代码的非Swing部分似乎正在主线程上运行)不同

System.out.println
将执行使用
synchronized
的代码,因此在这里可能作为有效的读取屏障

类似地,使用
调试器
将撤消许多
volatile
也禁用的优化,因此它可能具有相同的效果


private static boolean
更改为
private static volatile boolean

Simulator.main(args)不是异步调用。你可能想为此开始另一个线程。注意,任何终止
Simulator
的操作都将终止
Brain
@ElliottFrisch:这看起来像
Simulator。main
启动一个Swing窗口并返回,因此应用程序的Swing部分将继续运行。@JoachimSauer如果没有相关代码,很难确定,但我想你一定是正确的。我坚持评论,除非我对自己的猜测有信心。我还看到了一个
模拟器。getProgramMemory().getProgramMemory()
,这让我怀疑自己的理智。@ElliottFrisch那
模拟器。getProgramMemory().getProgramMemory()
是一件有趣的事情。我应该调用的第一个方法是
.getProgramMemory()
获取另一个
.getProgramMemory())
用于获取阵列。我对这些名字有点懒。。。。haha@JoachimSauer是的,你猜对了。伙计们,谢谢!>因此,它可能是一个有效的阅读障碍,这是邪恶的。是的,它是这样的,ATM是满内存刷新。我曾经见过一个
synchronized(newobject()){}
monstrosity用于这种效果。@pafauk:我从未见过故意使用它,我怀疑这是一个bug,因为据我所知
synchronized
只保证在同一对象上同步的线程之前会发生这种情况。在实践中,效果很可能比这要广泛得多,但这将是JVM的一个实现细节,依赖于它是一个坏主意。我的看法正是如此。尽管我坚信实现将超越完整的内存障碍,但我们一定要坚持JLS,因为它以前发生过(并与同步)