为什么等待线程延迟更新摆动组件?

时间:2017-06-07 15:34:37

标签: java multithreading swing callable

在等待并行任务完成之前,我无法理解为什么操纵摆动组件,即JProgressBar

在下面的示例中,progressBar只会在线程完成等待Callable的结果后激活其不确定模式,即使(我希望)setIndeterminate(true)的调用发生在等候。有人可以解释为什么会这样吗?

private void thisDoesntWork(JProgressBar p){
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<String> jobResult = executor.submit(() -> aLengthyJob());

    // This happens only after the button finishes waiting. (future.get())
    // I want to know why. Shouldn't this line happen before the thread blocks?
    p.setIndeterminate(true);

    try {
        System.out.println(jobResult.get());
    } catch (InterruptedException | ExecutionException ex) {}
}

public void createAndShowGUI(){
    JFrame frame = new JFrame("This progress bar wont work");
    JPanel panel = new JPanel();
    JButton button = new JButton("Start");
    JProgressBar progressBar = new JProgressBar();
    frame.setSize(500, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

    // Problem happens withing this button's action
    button.addActionListener((e)->{          
        thisDoesntWork(progressBar);
    });

    panel.add(button);
    panel.add(progressBar);
    frame.add(panel);
    frame.setVisible(true);

}

private String aLengthyJob(){
    try {
        Thread.sleep(10000);
    } catch (InterruptedException ex) {}
    return "Done";
}

public static void main(String[] args) {
    new Test().createAndShowGUI();
}

如果等待发生在另一个线程中,它会按预期工作。

// Waiting in a third thread works fine
private void thisWorks(JButton b, JProgressBar p) {
    p.setIndeterminate(true);
    b.setEnabled(false);

    ExecutorService executor = Executors.newFixedThreadPool(2);
    Future<String> jobResult;

    jobResult = executor.submit(() -> aLengthyJob());
    executor.execute(() -> {
        try {
            System.out.println(jobResult.get());
            p.setIndeterminate(false);
            b.setEnabled(true);
        } catch (InterruptedException | ExecutionException ex) {}
    });
}

进口:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

1 个答案:

答案 0 :(得分:4)

nightwatch -t tests/script.js等待EDT中其他线程的结束,阻止它。

  

也许你想至少链接到edt.- GhostCat

的某些背景知识

这里有一些关于EDT的资料:

https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

What is the event dispatching thread?