2011-07-30 2 views
6

나는 결과 JLabel의를 긴 작업을 수행하고 업데이트 할 SwingWorker의를 사용하려고 해요 정지됩니다 스레드가 실행되는 동안 Gui가 정지하는 지점에서 두 개의 스레드가 완료 될 때까지 응답을 유지합니다. 한 번에 하나의 스레드 만 실행하면이 문제가 계속 발생합니다.자바 GUI도 SwingWorker의

SwingWorker를 잘못 사용하고 있거나 다른 문제가있는 경우 누구나 지적 할 수 있다면 정말 대단 할 것입니다. 시간 내 줘서 고마워. 이안

편집

doCalculation()는 뭔가 시간이 소요됩니다 :

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

지금까지 게시 한 코드에 분명히 잘못된 것이 보이지 않지만 여기에서 핵심은'doCalculation();'에서 무슨 일이 일어나고 있는지 생각합니다. 이 코드를 게시 할 수 있습니까? –

답변

6

죄송하지만, 심지어 doCalculate() 메소드로, 나는 아직도 할 수 아니에요 문제를 재현 할 수 있습니다. 예를 들어 여기 내 sscce입니다 :

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(); 
     } 
     }); 
    } 
} 

당신은 (링크를 확인하십시오) 만들고 자신의 "Short, Self Contained, Correct (Compilable), Example" or SSCCE을 게시 할 수 있습니다. 이것을 만드는 과정에서 문제와 해결책을 직접 찾을 수있을 것입니다. 그렇다면 여기로 돌아와서 알려주십시오.

저는 이것이 실제로 답이 아니라는 것을 알고 있습니다. 그러나 주석에 이와 같은 코드를 게시 할 방법이 없습니다.

+1

도움 주셔서 감사합니다. 고맙습니다. 당신의 예에서도 똑같은 결말을 발견했습니다. 그래서 나는 그것으로 실험했습니다. 이클립스/명령 줄에서 실행하면 이것을 재현합니다. 나는 runnable 항아리를 만들었고 완벽하게 실행됩니다. 나는 64 비트 Windows 7을 실행 중입니다. 우분투로 시도했는데 문제도 해결 한 것 같습니다. 다시 한번 감사드립니다. – Ian

+0

나는 Listener 내부에서 결코 보지 않는다. 나는 put ..., 그러나 당신의 포스트, 아마 가능한 방법, 멋진 예제, 성능 문제가 없다고 확신하지 않는다. +1 – mKorbel

+1

@Ian : 흠, 그래도 여전히 좋을 것이다. 그러한 특정 상황에서 왜 얼어 붙는 지 알아야합니다. 아마도 너무 많은 스레드와 관련이 있습니다. 여러 스레드를 처리 할 때 SwingWorker를 사용할 수 없을 때 ExecutorService와 스레드 풀을 사용해야한다고 들었습니다. –