2016-01-06 79 views
1

在面試中,我被問到:「如何在單線程中執行多個計算而不凍結GUI組件,例如進度條或能夠檢查另一個用戶輸入? (只能執行一個線程)「Java沒有凍結的長時間計算GUI(單線程)

我問過可以像Node.js那樣編寫事件循環。 但是我說Java已經有了一些機制。 Java可以使用硬件並行操作。這些任務可以使用哪些類別或特殊字詞?

+0

像'javax.swing.SwingWorker'? [Doc](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) – scsere

+0

不,SwingWorker運行新線程。 – IntFloat

+0

是的,我評論之前,你改變標題爲**單線程**;) – scsere

回答

3

因此,假設我們不能使用任何SwingWorker或Swing Timer,爲他們創造第二個線程來支持他們的行動,只留給你的選擇是使用SwingUtilities#invokeLater重複調用的方法,其執行工作,並再次調用本身之前更新UI的小部分(使用SwingUtilities#invokeLater

Look ma, no threads

import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class NoMoreThreads { 

    public static void main(String[] args) { 
     new NoMoreThreads(); 
    } 

    public NoMoreThreads() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static class TestPane extends JPanel { 

     protected static final int MAX = 1000; 

     private JProgressBar pb; 
     private JButton start; 
     private int count; 

     public TestPane() { 
      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      start = new JButton("Let's get this party started"); 
      start.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        start.setEnabled(false); 
        calculate(); 
       } 
      }); 

      pb = new JProgressBar(0, MAX); 

      add(start, gbc); 
      add(pb, gbc); 
     } 

     protected void calculate() { 
      count++; 
      if (count < MAX) { 
       pb.setValue(count); 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         calculate(); 
        } 
       }); 
      } else { 
       start.setEnabled(true); 
      } 
     } 

    } 

} 
+0

這顯然不是什麼關於面試官說。 – IntFloat

+0

爲什麼?這不凍結用戶界面,不使用任何其他線程?既然你似乎無法解決它,你怎麼知道這不是一個可行的解決方案? – MadProgrammer

+0

基於你的問題的措辭,[this](http://www.oracle.com/technetwork/articles/java/fork-join-422606.html)似乎是他們正在談論的內容,這是一個清晰的因爲這仍然會創建一個後臺線程 – MadProgrammer