Java-volatile变量未更新

Java-volatile变量未更新,java,multithreading,javafx-2,javafx,volatile,Java,Multithreading,Javafx 2,Javafx,Volatile,我正在使用JavaFx开发一个交互式排序应用程序: 数字用矩形表示 每次交换两个数字时,矩形就会交换(使用时间线-动画) 这是排序算法之一: public class BubbleSort implements SortAlgorithm { private volatile Boolean swaping; public void sort(double[] array, CompareFunction compareFunction, Model model, Controller

我正在使用JavaFx开发一个交互式排序应用程序:

  • 数字用矩形表示
  • 每次交换两个数字时,矩形就会交换(使用时间线-动画)
这是排序算法之一:

 public class BubbleSort implements SortAlgorithm {
private volatile Boolean swaping;

public void sort(double[] array, CompareFunction compareFunction, Model model, Controller controller) {
    Boolean ord;
    int i;
    double aux;

    swaping = false;

    do {
        ord = true;

        for (i = 0; i < array.length - 1; i++) {
            if (compareFunction.compare(array[i], array[i + 1]) == false) {
                while (swaping);

                swaping = true;

                aux = array[i];
                array[i] = array[i + 1];
                array[i + 1] = aux;
                ord = false;

                controller.swapRectangles(model.getRectangles().get(i), model.getRectangles().get(i + 1), this);
            }
        }
    } while (ord == false);
}

public void setSwaping(Boolean swaping) {
    this.swaping = swaping;
}
当时间线结束时,我计算“交换”值:

timeline2.setOnFinished(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent ActionEvent){
setRectangleFill(矩形2,颜色为黑色);
矩形2.setX(矩形1X);
bubbleSort.Setswapping(假);
}
});
问题是“swaping”变量永远不会更新(setSwaping方法永远不会被调用)


你知道为什么吗

我认为您在
setSwaping
方法中更新了
swaping=true
,但在sort方法中,您在循环执行之前再次设置了
swaping=false
。所以我认为while循环永远不会执行,因为swap是错误的。所以您假设该值没有被更新

排序方法中删除此行:

swaping = false;


while (swaping);
删除
并将代码放入while block中

  • 运行
    时(交换)对处理器施加了巨大的压力,您正在获取它的全部能量,并将其交给“不做任何事情”循环。要解决这个问题,可以在线程中添加sleep:while(swap)Thread.sleep(100)或使用更方便的同步机制,如

  • 另外,如果在UI线程上运行
    sort
    ,则会完全阻止它,因此
    setOnFinished
    将永远不会有机会运行。您应该在单独的线程上运行
    sort

    new Thread() {
        public void run() {
            new BubbleSort().sort(array, compareFunction, model, controller);
        }
    }.start();
    

  • 如果您从此线程更新UI,请确保将UI调用包装到中。

    您如何知道它没有更新?因为应用程序已冻结。在“swap”变为“true”后,它不会从“while(swap);”传递。应用程序在第一次交换后冻结。当“swap”变为“true”时,下一次“swap”将永远不会经过“while(swap)”;“我删除了该行,应用程序仍然冻结。不,我放在那里”;“因为动画的持续时间为1s,“下一次swap”必须等待动画结束。@JohnSmith但如果swap为true,则会导致无限循环。是的,但我更新了“swap”这里:timeline2.setOnFinished(neweventhandler(){@Override public void handle(ActionEvent-ActionEvent){setRectangleFill(rectangle2,Color.BLACK);rectangle2.setX(rectangle1X);bubbleSort.setswapping(true);});
    swaping = false;
    
    
    while (swaping);
    
    new Thread() {
        public void run() {
            new BubbleSort().sort(array, compareFunction, model, controller);
        }
    }.start();