在面試中,我被問到:「如何在單線程中執行多個計算而不凍結GUI組件,例如進度條或能夠檢查另一個用戶輸入? (只能執行一個線程)「Java沒有凍結的長時間計算GUI(單線程)
我問過可以像Node.js那樣編寫事件循環。 但是我說Java已經有了一些機制。 Java可以使用硬件並行操作。這些任務可以使用哪些類別或特殊字詞?
在面試中,我被問到:「如何在單線程中執行多個計算而不凍結GUI組件,例如進度條或能夠檢查另一個用戶輸入? (只能執行一個線程)「Java沒有凍結的長時間計算GUI(單線程)
我問過可以像Node.js那樣編寫事件循環。 但是我說Java已經有了一些機制。 Java可以使用硬件並行操作。這些任務可以使用哪些類別或特殊字詞?
因此,假設我們不能使用任何SwingWorker
或Swing Timer
,爲他們創造第二個線程來支持他們的行動,只留給你的選擇是使用SwingUtilities#invokeLater
重複調用的方法,其執行工作,並再次調用本身之前更新UI的小部分(使用SwingUtilities#invokeLater
)
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);
}
}
}
}
這顯然不是什麼關於面試官說。 – IntFloat
爲什麼?這不凍結用戶界面,不使用任何其他線程?既然你似乎無法解決它,你怎麼知道這不是一個可行的解決方案? – MadProgrammer
基於你的問題的措辭,[this](http://www.oracle.com/technetwork/articles/java/fork-join-422606.html)似乎是他們正在談論的內容,這是一個清晰的因爲這仍然會創建一個後臺線程 – MadProgrammer
像'javax.swing.SwingWorker'? [Doc](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) – scsere
不,SwingWorker運行新線程。 – IntFloat
是的,我評論之前,你改變標題爲**單線程**;) – scsere