[英]Running multiple Threads on multiple JPanels and switch them
我有一個帶多線程的TCP Server,可以從cli處理它。
現在,我想為其編寫一個GUI,以便可以輕松地啟動,監視,管理和退出該多線程服務器的特定實例。 首先,我想到了JTable,這也是我的第一個問題:
在JTable內處理多個套接字(而不是線程)上的多個服務器線程是否是一種好方法(甚至可能),並且我能夠根據套接字活動向其發送數據以更新單個行嗎? 我的意思是,當每一行代表一個正在運行的服務器線程時,用戶應該能夠單擊它,啟動一個新的服務器線程(將添加到列表中),在字段中查看socketstatus(無論如何),查看有多少客戶端已連接,甚至可以通過該表停止特定線程?
我的第二個問題是:
當我以上述方式開始實現它時,用另一個接口更新活動的JPanel並再次切換回去時,jtable和正在運行的線程會怎樣? 例如,我有一個界面可概述所有實例,而另一個界面可提供有關單個實例的詳細信息。 是所有線程都會中斷還是在此之后又可以與表通信? 還是使用cardLayout更好?
當我在cardlayout上更換卡時,該卡上正在運行某些東西(例如,具有運行套接字線程的JTable),它們會被中斷或停止,還是可以再更新JTable中的statusdata? 因此,套接字應該能夠全部向表寫入和更新數據。
現在是我的最后一個問題,感謝您閱讀了這么長時間。 在嘗試找到上述所有問題的答案時,我嘗試了一個簡單的JPanel切換框架,每個面板上都有一個JTextarea,可寫入100行,且間隔為1000ms。 然后,我想切換面板,看看該任務是否被中斷。 不幸的是,我什至無法解決這個問題。
在外部類MyPanel中,我將啟動具有單獨配置的JPanel並將其添加到主框架。
for循環僅用於測試:
class MyPanel extends JPanel {
public static JTextArea tArea;
public MyPanel(String config) {
JButton testButton = new JButton(config);
add(testButton);
tArea = new JTextArea();
JScrollPane scroll = new JScrollPane(tArea);
add(scroll, BorderLayout.CENTER);
for (int i = 0 ; i < 50 ; i ++ ) {
tArea.append("test \n") ;
try { Thread.sleep(2000); } catch(InterruptedException ie) {}
}
setVisible(true);
revalidate();
repaint();
}
}
但是我認為,這是完全錯誤的,因為我在重新驗證和重新繪制之前調用它:(在大型機內部,我想以這種方式啟動它:
JMenuItem menuItem = new JMenuItem("Test");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
MyPanel dynamicPanel = new MyPanel("Test");
contentContainer.removeAll();
contentContainer.add(dynamicPanel);
contentContainer.revalidate();
contentContainer.repaint();
}
});
您需要了解的第一件事,Swing是一個單線程框架,並且不是線程安全的。 這意味着所有與UI的更新和交互都必須在UI線程(事件調度線程)內進行,請參見Swing中的並發
在JTable中處理多個套接字(而非線程)上的多個服務器線程是否是一種好方法(甚至可能),並且我能夠根據套接字活動向其發送數據以更新單個行嗎? 我的意思是,每行代表一個正在運行的服務器線程時,用戶應該可以單擊它,開始一個新的(將被添加到列表中),在字段中查看socketstatus(無論將是什么),查看有多少客戶端已連接,甚至可以通過該表停止特定線程?
老實說,我認為這並不重要,您遇到的問題是從線程/套接字向UI獲取信息。 我要考慮做的是擁有一個Thread
其唯一目的是輪詢所有其他線程/套接字以獲取信息,然后將該信息與UI同步,以確保在該過程中不違反Swing的單線程規則。 根據您的設計,在這里SwingWorker
可能是一個不錯的選擇。
我不考慮讓每個線程分別向UI發送信息的原因是,這將是淹沒EDT並導致其滯后的一種很好的方法,而它試圖處理系統可能創建的大量數據
當我以上述方式開始實現它時,當我使用另一個接口更新活動的JPanel並再次切換回時,jtable和正在運行的線程會怎樣? 例如,我有一個界面可提供所有實例的概述,而另一個界面可提供有關單個實例的詳細信息。 所有線程都將被中斷,還是可以在此之后再次與表通信? 還是使用cardLayout更好?
當我在cardlayout上更換卡時,在該卡上正在運行的東西(例如,具有運行套接字線程的JTable)會被中斷或停止,還是可以再更新JTable中的statusdata? 因此套接字應該能夠將數據全部寫入和更新到表中。
根據我上面的描述,在后台運行的線程基本上不會發生任何事情,因為它們已與UI斷開連接。 “輪詢”線程將仍在運行,並且仍將向表發送更新(我希望通過TableModel
),但是,由於它實際上在屏幕上不可見,因此不會被繪制,並且“不應”產生不利影響系統的性能。
這提出了某種“狀態”模型的思想。 該模型實際上可以用於描述單個線程的狀態,然后可以由“狀態”管理器進行管理,該管理器使您可以訪問此信息(以及實際線程)。 輪詢線程將從正在運行的線程/套接字獲取信息並更新該線程的關聯“狀態”模型,這意味着您可以掛起它的整個UI,並且知道在訪問它時,只能從內部對其進行修改EDT的上下文-沒有死鎖或競爭條件。 作為一個想法
現在是我的最后一個問題,感謝您閱讀了這么長時間。 在嘗試發現上述所有問題的答案時,我嘗試了一個簡單的JPanel切換框架,每個面板上都有一個JTextarea,可寫入100行,且間隔為1000ms。 然后我想切換面板,看看該任務是否被中斷。 該死的我真是個菜鳥,我什至不能帶這個去上班。
在外部類MyPanel中,我將啟動具有單獨配置的JPanel並將其添加到主框架。
這是因為您的代碼阻塞了事件處理線程,該線程負責處理事件隊列,該事件隊列還攜帶重繪事件(除其他事項外),這意味着,在循環運行時,無法更新UI (或與之互動)。
使用SwingWorker
可以更好地提供代碼。
有關更多詳細信息,請參見Swing和Worker線程中的 並發 和SwingWorker 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.