Java - volatile变量未更新

时间:2013-04-21 13:44:27

标签: 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 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;
}

}

这是swapRectangles方法的原型:

public void swapRectangles(final Rectangle rectangle1, final Rectangle rectangle2,    final BubbleSort bubbleSort)

当时间轴结束时,我会更换“交换”值:

        timeline2.setOnFinished(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            setRectangleFill(rectangle2, Color.BLACK);
            rectangle2.setX(rectangle1X);
            bubbleSort.setSwaping(false);
        }
    });

问题是“交换”变量永远不会更新(从不调用setSwaping方法)。

你知道为什么吗?

2 个答案:

答案 0 :(得分:3)

  1. 运行while(swaping);给处理器带来了巨大的压力,你正在全力以赴并将其交给“无所事事”循环。要解决此问题,请在内部添加sleep while(swaping) Thread.sleep(100);或使用更方便的同步机制,如Semaphore

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

    new Thread() {
        public void run() {
            new BubbleSort().sort(array, compareFunction, model, controller);
        }
    }.start();
    
  3. 如果您从此线程更新UI,请确保将UI调用包装到Platform.runLater

答案 1 :(得分:0)

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

sort方法中删除此行:

swaping = false;


while (swaping);

删除;并在阻止时将代码放入其中。