Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.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
即使使用SwingWorker,Java GUI也会冻结_Java_Multithreading_Swing_Swingworker - Fatal编程技术网

即使使用SwingWorker,Java GUI也会冻结

即使使用SwingWorker,Java GUI也会冻结,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,我正在尝试使用SwingWorker执行一项冗长的任务,并使用以下结果更新JLabel: button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { new SwingWorker<String, Void>() { @Override protect

我正在尝试使用SwingWorker执行一项冗长的任务,并使用以下结果更新JLabel:

button.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        new SwingWorker<String, Void>() {

            @Override
            protected String doInBackground() throws Exception {
                return doCalculation();
            }

            protected void done() {
                try {
                    label.setText(get());
                } catch (InterruptedException e) {
                    System.out.println("thread was interrupted");
                } catch (ExecutionException e) {
                    System.out.println("there was an ExecutionException");
                }
            }

        }.execute();

    }

});
button.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
新SwingWorker(){
@凌驾
受保护的字符串doInBackground()引发异常{
返回doccalculation();
}
受保护的void done(){
试一试{
label.setText(get());
}捕捉(中断异常e){
System.out.println(“线程被中断”);
}捕获(执行例外){
System.out.println(“存在执行异常”);
}
}
}.execute();
}
});
我可以随意多次单击该按钮,Gui将保持响应,直到两个线程完成,此时Gui在线程运行时冻结。如果我一次只运行一个线程,这个问题仍然会发生

如果有人能指出我是否错误地使用了SwingWorker,或者是否有其他我不知道的问题,我将不胜感激。谢谢你抽出时间。 伊恩

编辑

doCalculation()只是一个耗时的过程:

private String doCalculation() {
    for (int i = 0; i < 10000000; i++) {
        Math.pow(3.14, i);
    }
    return threads++ + "";
}
private String doccalculation(){
对于(int i=0;i<10000000;i++){
数学.pow(3.14,i);
}
返回线程+++;
}

很抱歉,即使使用doCalculate()方法,我仍然无法重现您的问题。例如,下面是我的:

导入java.awt.event.*;
导入java.util.concurrent.ExecutionException;
导入javax.swing.*;
公共类FooGui{
私有静态int线程=0;
私有静态void createAndShowUI(){
最终JLabel标签=新JLabel(“”);
JButton按钮=新JButton(“按钮”);
addActionListener(新建ActionListener()){
@凌驾
已执行的公共无效操作(操作事件arg0){
新SwingWorker(){
@凌驾
受保护的字符串doInBackground()引发异常{
返回doccalculation();
}
@凌驾
受保护的void done(){
试一试{
label.setText(get());
}捕捉(中断异常e){
System.out.println(“线程被中断”);
}捕获(执行例外){
System.out.println(“存在执行异常”);
}
}
}.execute();
}
});
JPanel面板=新的JPanel();
面板。添加(按钮);
面板。添加(标签);
JFrame=newjframe(“FooGui”);
frame.getContentPane().add(面板);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
私有静态字符串doCalculation(){
对于(int i=0;i<5000000;i++){
数学.pow(3.14,i);
}
返回线程+++;
}
公共静态void main(字符串[]args){
invokeLater(new Runnable()){
@凌驾
公开募捐{
createAndShowUI();
}
});
}
}
您可能希望创建并发布您自己的(请检查链接)。我敢打赌,在创建这个过程中,您可能会自己找到问题及其解决方案。如果是这样,请务必回到这里,让我们知道


我知道这不是一个真正的答案,但是没有办法在评论中发布这样的代码

到目前为止,我没有看到您发布的代码有任何明显的错误,但我认为这里的关键是
doccalculation()中发生的事情方法。你能发这个代码吗?谢谢你的帮助,我很感激。我在你的例子中也发现了同样的冻结,所以我尝试了一下。从eclipse/命令行运行可以复制这一点。我创建了一个可运行的jar,它运行得非常好。我正在运行64位Windows7。我在Ubuntu上试过,似乎也解决了这个问题。再次感谢。我从来没有看到过那个内在的监听器,我不确定放…,但你的帖子,这可能是可行的方式,很好的例子,没有性能问题+1@Ian:嗯,如果能知道为什么在某些情况下会发生冰冻,那就太好了。也许这与线程太多有关。我听说在处理多个线程时,有时不能使用SwingWorker,而需要使用ExecutorService和线程池。我的应用程序也有类似的问题,通过IDE运行它也是我的问题。
import java.awt.event.*;
import java.util.concurrent.ExecutionException;
import javax.swing.*;

public class FooGui {
   private static int threads = 0;

   private static void createAndShowUI() {
      final JLabel label = new JLabel("      ");
      JButton button = new JButton("Button");
      button.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            new SwingWorker<String, Void>() {

               @Override
               protected String doInBackground() throws Exception {
                  return doCalculation();
               }

               @Override
               protected void done() {
                  try {
                     label.setText(get());
                  } catch (InterruptedException e) {
                     System.out.println("thread was interrupted");
                  } catch (ExecutionException e) {
                     System.out.println("there was an ExecutionException");
                  }
               }
            }.execute();
         }
      });
      JPanel panel = new JPanel();
      panel.add(button);
      panel.add(label);

      JFrame frame = new JFrame("FooGui");
      frame.getContentPane().add(panel);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   private static String doCalculation() {
      for (int i = 0; i < 5000000; i++) {
         Math.pow(3.14, i);
      }
      return threads++ + "";
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {

         @Override
         public void run() {
            createAndShowUI();
         }
      });
   }
}