簡體   English   中英

捕獲異常后重新啟動線程

[英]restart a thread after exception is caught

我正在讀取UDP提要,並且如果線程失敗,我希望線程嘗試重新啟動。 我想我已經正確地寫了我的課,但想找人看一下,看看是否有遺漏的東西,或者我寫的東西無法完成工作。 在我的catch子句中,我嘗試每6秒重新啟動一次線程,進行10次嘗試。 這是一個好的解決方案,它會起作用嗎?

class UDPReader extends Thread
{
    private Thread t;
    private final String ip, socket, queue, threadName;
    private String ErrorMessage;
    private final JTextArea screen;

    UDPReader(String ip, String socket, String queue, String threadName, JTextArea screen) {
        this.ip = ip;
        this.socket = socket;
        this.queue = queue;
        this.threadName = threadName;
        this.screen = screen;
    }

    public void run()
    {
        try {
            byte[] i = null;
            ipaddrConnection ipaddr = new ipaddrConnection(ip, socket);
            parseUDP p = new parseUDP();

            screen.append("Thread " + threadName + " running\n");
            while(true)
            {
                i = ipaddr.getPacket();
                p.parseUDP(i); 
                //Thread.sleep(0);
            }
        } 
        catch (IOException ex) {
            Logger.getLogger(MarketDataReader.class.getName()).log(Level.SEVERE, null, ex);
            ErrorMessage = "Thread " + threadName + " has failed, Attempting to Restart";
            screen.append("Thread " + threadName + " has failed, Attempting to Restart\n");
            Email email = new Email(ErrorMessage,"WARNING Market Data Reader Failure");

            for(int i = 0; i < 10 && t.isAlive() == false; i++)
            {
                try {
                    start();
                    Thread.sleep(6000);
                } catch (InterruptedException ex1) {
                    Logger.getLogger(UDPReader.class.getName()).log(Level.SEVERE, null, ex1);
                    ErrorMessage = "Thread " + threadName + " has failed, Contact System Administraitor";
                    screen.append("Thread " + threadName + " has failed, Contact System Administraitor\n");
                    email = new Email(ErrorMessage,"WARNING Market Data Reader Failure");
                }
            }
        }
    }

    public void start() 
    {
        if (t == null)
      {
         t = new Thread (this, threadName);
         t.start ();
      }
    }
}

我不知道您線程的詳細邏輯,但我會對您的代碼設計提出一些建議。

  1. 目前尚不清楚為什么在從線程派生的類中有另一個線程t。

  2. 不需要從Thread派生(我認為這通常是一種不好的做法)。 通常,寧可實現Runnable接口,然后使用該接口構造一個新線程。

class UDPReader implements Runnable {
...
}

然后實例化這樣的線程:

Thread t = new Thread(new UDPReader());
  1. 通常,如果線程失敗,則線程終止...失敗的線程自身“重新創建”看起來並不好。 更好的解決方案是提供Thread.UncaughtExceptionHandler並在創建線程的代碼中分析失敗情況並在需要時重新啟動線程。

通常,為了避免混亂,在並發編程中,您必須清楚地區分線程的邏輯和管理該線程的外部邏輯(其啟動/中斷/終止)。 我認為,這是您在代碼中未執行的操作。

我想說,從同一線程內部重新啟動線程是一個非常糟糕的設計。

如果您需要一個“主管”線程,那么您很可能應該創建另一個“主管”線程,該線程將在發現“工人”線程關閉時創建並啟動“工人”線程。

您應該意識到的一件事是,當您在Java中捕獲異常時,程序(或線程)不會終止,除非您也告訴了它。

因此,如果您恰好在導致異常發生的命令(循環內)中捕獲了異常,則無需運行其他線程。 您的線程仍然存在,並且將繼續循環。 您需要做的-在catch塊內-修復問題,以便下一個循環可以照常繼續-關閉並重新打開流,清除部分填充的數據結構,諸如此類。

當然,如果發生進一步的不可恢復的異常,則確實應該停止線程。

暫無
暫無

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

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