Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:While循环不退出_Java - Fatal编程技术网

Java:While循环不退出

Java:While循环不退出,java,Java,有人知道为什么只有存在System.out.println()时才会出现这种while look吗 如果我注释掉println(),同样的代码就不起作用 节目如下 static final int gridSize = Integer.parseInt(InOut.in(1, "Enter grid size")); static Tile[][] board = new Tile[gridSize][gridSize]; static int winCond = 1; static GuiFr

有人知道为什么只有存在System.out.println()时才会出现这种while look吗

如果我注释掉println(),同样的代码就不起作用

节目如下

static final int gridSize = Integer.parseInt(InOut.in(1, "Enter grid size"));
static Tile[][] board = new Tile[gridSize][gridSize];
static int winCond = 1;
static GuiFrame f = new GuiFrame(gridSize);
static BtnPanel p = new BtnPanel(gridSize);
static JButton[][] btn = new JButton[gridSize][gridSize];

public static void main(String[] args) {

    //Creating objects
    for (int i = 0; i < gridSize; i++) {
        for (int z = 0; z < gridSize; z++) {
            board[i][z] = new Tile();
        }
    }
    GUI();

    while (!hasWon()) {

        System.out.println("");

        if(hasWon()){
            InOut.out(output() + "\nYou Won");
            System.exit(0);
        }
    }
}

public static boolean hasWon() {
    boolean hasWon = true;

    for (int i = 0; i < gridSize; i++) {
        for (int z = 0; z < gridSize; z++) {
            hasWon = hasWon && (board[i][z].getStatus() == winCond);
        }
    }

    return hasWon;
}

public static String output() {
    String message = "";

    for (int i = 0; i < gridSize; i++) {
        for (int z = 0; z < gridSize; z++) {
            message += board[i][z].getStatus() + " ";
        }
        message += "\n";
    }

    return message;
}

public static void GUI() {

    for (int i = 0; i < gridSize; i++) {
        for (int z = 0; z < gridSize; z++) {
            String btnValue = "";
            btnValue += board[i][z].getStatus();
            btn[i][z] = new JButton();
            btn[i][z].setText(btnValue);
            btn[i][z].addActionListener(f);
            p.add(btn[i][z]);
        }
    }

    f.add(p, BorderLayout.CENTER);

}

public static void modifyGUI(int i, int z){
    btn[i][z].setText(String.valueOf(board[i][z].getStatus()));
}
static final int gridSize=Integer.parseInt(InOut.in(1,“输入网格大小”);
静态磁贴[][]板=新磁贴[gridSize][gridSize];
静态int winCond=1;
静态GuiFrame f=新GuiFrame(gridSize);
静态BtnPanel p=新BtnPanel(网格大小);
静态JButton[][]btn=新JButton[gridSize][gridSize];
公共静态void main(字符串[]args){
//创建对象
对于(int i=0;i
这是一个益智游戏,用户点击一个瓷砖,相邻的瓷砖也会改变。但是,当拼图完成时,如果没有println(),则不显示完成,如果有println(),则退出循环并退出程序


再次强调一下,如果while循环中有println(),一切都可以正常工作。当我评论它不起作用时。

它现在起作用的事实是一个意外。如果要强制计算机在每次通过循环时重新检查变量,则需要声明变量
volatile
;否则,它可能只读取一次值,而不再查看它


此外,像这样繁忙的等待循环效率极低。相反,如果您想在win中退出,请让设置该标志的代码直接调用关机代码

它现在起作用的事实是一个意外。如果要强制计算机在每次通过循环时重新检查变量,则需要声明变量
volatile
;否则,它可能只读取一次值,而不再查看它


此外,像这样繁忙的等待循环效率极低。相反,如果您想在win中退出,请让设置该标志的代码直接调用关机代码

您拥有的是一个紧凑的CPU密集型循环,它反复调用
haswen()
。看起来还有其他线程负责更新导致“赢”位置的板状态

看起来问题在于CPU循环太紧导致另一个线程耗尽,插入
println
就足以让线程调度程序重新调度

另一种可能的解释是,您有一个共享的数据结构,一个线程正在读取,另一个线程正在更新。。。没有任何同步。从理论上讲,不同步的事实可能意味着更新线程所做的更改永远不会被读取线程看到,因为编译器没有看到需要插入会导致相关缓存刷新等的“屏障”指令


正如@chrylis所指出的,像这样繁忙的循环效率非常低。您需要做的是替换繁忙的循环:

  • 一个有技巧的解决方案是将
    Thread.sleep()
    调用放入循环中(而不是
    println
    调用)

  • 更好的解决方案是使用
    Object.wait()
    Object.notify()
    。主线程在每次检查后对互斥对象调用
    wait()
    ,而进行更新的线程在每次执行可能导致“赢得”位置的更新时都对同一互斥对象调用
    notify()

第二个解决方案还处理同步问题。
wait()
notify()
方法只能在保持互斥锁的情况下执行;i、 e.在
同步的
块或方法中


下面是一些代码片段,说明如何实现wait/notify

    public static final Object mutex = new Object();
    public static boolean finished = false;

    // One thread
    synchronized (mutex) {
        while (!finished) {
             mutex.wait();
        }
    }

    // Another thread
    synchronized (mutex) {
        finished = true;
        mutex.notify();
    }

显然,使用静力学只是为了说明目的

您拥有的是一个紧凑的CPU密集型循环,它反复调用
haswen()
。看起来还有其他线程负责更新导致“赢”位置的板状态

看起来问题在于CPU循环太紧导致另一个线程耗尽,插入
println
就足以让线程调度程序重新调度

另一种可能的解释是,您有一个共享的数据结构,一个线程正在读取,另一个线程正在更新。。。没有任何同步。从理论上讲,不同步的事实可能意味着更新线程所做的更改永远不会被读取线程看到,因为编译器没有看到需要插入会导致相关缓存刷新等的“屏障”指令


正如@chrylis所指出的,像这样忙碌的循环是可怕的
    public static final Object mutex = new Object();
    public static boolean finished = false;

    // One thread
    synchronized (mutex) {
        while (!finished) {
             mutex.wait();
        }
    }

    // Another thread
    synchronized (mutex) {
        finished = true;
        mutex.notify();
    }
Thread,sleep(100L);
        hasWon = hasWon && (board[i][z].getStatus() == winCond);
        if (board[i][z].getStatus() != winCond) {
            return false;
        }