我正在創(chuàng)建一個 Swing 應(yīng)用程序。它包含一個 JFrame,在 JFrame 內(nèi)部,我添加了一個 JButton 來啟動和停止一些任務(wù)。我正在使用相同的 JButton 來啟動和停止作為線程并由 ExecutorService 執(zhí)行的任務(wù)。單擊開始按鈕時,將執(zhí)行線程并且按鈕標(biāo)簽將更改為停止,而單擊停止按鈕將停止所有線程(我已使用 ExecutorService shutdownNow() 方法完成此操作)并且按鈕標(biāo)簽將再次出現(xiàn)更改為開始,但應(yīng)用程序不會關(guān)閉?,F(xiàn)在,如果我再次單擊“開始”按鈕,應(yīng)用程序?qū)⒈粧炱穑€程不會從頭開始重新啟動。import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;public class MultipleThreads { public static ExecutorService executor = Executors.newFixedThreadPool(4); public static void main(String[] args) { JFrame frame = new JFrame("Stop Thread"); frame.setSize(200,200); frame.setLocationRelativeTo(null); frame.setLayout(null); JPanel panel = new JPanel(); panel.setBounds(5,5,150,150); panel.setLayout(null); JButton btn = new JButton("Start"); btn.setBounds(10,10,80,25); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { if (btn.getText().equals("Start")) { btn.setText("Stop"); MultipleThreads2 runThreads = new MultipleThreads2(); runThreads.runThreadMethod(); } else if (btn.getText().equals("Stop")) { try { if (!executor.awaitTermination(800, TimeUnit.MILLISECONDS)) { executor.shutdownNow(); } } catch (InterruptedException e) { executor.shutdownNow(); } btn.setText("Start"); } } }); panel.add(btn); frame.add(panel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }}預(yù)期:第二次單擊“開始”按鈕時,應(yīng)從頭開始重新啟動所有線程。
1 回答

叮當(dāng)貓咪
TA貢獻(xiàn)1776條經(jīng)驗 獲得超12個贊
這里:
public static ExecutorService executor = Executors.newFixedThreadPool(4);
您正在創(chuàng)建一次該線程池。稍后,你打電話
executor.shutdownNow();
換句話說:你正在啟動你的車,在某個時刻,你停下車,下車,然后把它點(diǎn)燃。然后你問自己:“好吧,我怎么用那輛車開車回家?”。好吧,你不能。你只是把它點(diǎn)燃了。
同樣的事情:當(dāng)你關(guān)閉服務(wù)時,它就消失了。
長話短說,一個簡單(不一定理想)的解決方案是:
public static ExecutorService executor = null;
后來:
if (executor == null) executor = Executors.newFixedThreadPool(4);
和
executor.shutdownNow(); executor = null;
換句話說:你開著你的車,你把它點(diǎn)燃,然后你買了一輛新的,再開一輛,然后再把它點(diǎn)燃。
當(dāng)然,設(shè)置為 null 并檢查它的方法可能會導(dǎo)致各種問題。這樣做會更好一些:
executor.shutdownNow(); executor = Executors.newFixedThreadPool(4);
含義:只要告訴“最后一個”關(guān)閉,您只需創(chuàng)建一個新實(shí)例,而不是將執(zhí)行程序保留為空。因此,理論上,每當(dāng)執(zhí)行器習(xí)慣于提交任務(wù)或它被關(guān)閉時,您正在與當(dāng)前“有效”的實(shí)例交談。
添加回答
舉報
0/150
提交
取消