簡體   English   中英

EDT與主線程之間的通信

[英]Communication between the EDT and main threads

關於我最近從事的一個項目,我一直問很多問題。 這是我所處的場景,任何幫助或指出正確的方向都會有很大幫助...

這是一個由服務器和多個客戶端構建的網絡程序。 每個客戶端都有一個GUI,該GUI必須根據服務器發送的命令進行操作。 每個客戶端都包裝在一個名為Player的類中。 Player具有GUI(擴展了JFrame )和main方法,而Server僅具有main方法(沒有GUI)。 首先,此類是在主線程中創建的,如下所示:

EventQueue.invokeLater(new Runnable()
{
    public void run()
    {
        new Player().setVisible(true);
    }
 });

一切正常,直到我意識到整個Player類現在都在EDT中執行。 因此,當我等待來自服務器的命令時,整個GUI都會鎖定,直到發送該命令並執行適當的操作為止。 可以想象,這是一個可怕的設計,並且在每次要檢查某項內容時都必須進行一些瘋狂的處理才能使GUI保持完整,這是編碼環境的真正痛苦。

顯然,我必須在單獨的線程中檢查來自服務器的命令,然后在EDT中運行GUI組件。 我的第二個實現有兩個類:一個用於GUI,一個用於Player 這個想法是Player具有一個保存GUI的變量,以便我可以從Player類訪問GUI,如下所示:

class Player
{
    public GUI gui;

    ...

    // And then start this gui inside of the EDT.
    EventQueue.invokeLater(new Runnable()
    {
         public void run()
         {
              this.gui = new GUI().setVisible(true);
         }
    }

這也不行,因為this新的內部Runnable對象指Runnable對象,而不是Player

如何在一個線程中的Player類與EDT線程中的相應GUI類之間進行通信?

要使用this指針處理問題,您應該編寫:

class Player
{
    public GUI gui;

    ...

    // And then start this gui inside of the EDT.
    EventQueue.invokeLater(new Runnable()
    {
         public void run()
         {
              Playser.this.gui = new GUI().setVisible(true);
         }
    }
}

BorisPavlović正確使用了語法(實際上您可以刪除this. ),但是代碼仍然沒有意義。 gui字段在Runnable事件排隊后的某個時間初始化,因此播放器線程使用它是不安全的。

您可以在EDT上構造Player ,但可以在EDT上進行網絡操作。 或將GUI注冊為Player的偵聽器(觀察者)。 invokeAndWait可以工作,但是很危險,因為它經常導致偶爾難以調試的死鎖。

您可以嘗試以下方法:

class Player {公共GUI gui;

...

// And then start this gui inside of the EDT.
EventQueue.invokeLater(new Runnable()
{
     public void run()
     {
          Player.this.gui = new GUI().setVisible(true);
     }
}

“直到我意識到整個Player類現在都在EDT中執行”

構造函數在EDT上發生,但在此類上調用的方法可能不是。

您應該按照最初的意圖構造播放器GUI。

 EventQueue.invokeLater(new Runnable() 
 {
    public void run()
    {
        new Player().setVisible(true);
    }
 });

但是Player可以在構造函數中啟動一個單獨的線程(我個人希望在Player之間共享一個連接)。

當然,修改可見組件時,服務器的回調方法應使用invokeLater()。

與其使用匿名內部類,不如聲明一個實現Runnable並具有以GUI實例作為參數的構造函數的類?

另外,如果您的GUI類不是線程安全的,請考慮使用消息隊列在EDT和主線程之間進行通信。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM