捕获异常后重启线程

时间:2014-10-28 16:46:21

标签: java multithreading

我正在读取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 ();
      }
    }
}

3 个答案:

答案 0 :(得分:2)

我不清楚你的线程背后的逻辑,但我会对你的代码设计提出一些建议。

  1. 目前尚不清楚为什么在从线程派生的类中有另一个线程t。

  2. 没有必要从Thread派生(我相信这通常是一种不好的做法)。通常是实现Runnable接口,然后使用它构造一个新线程。

  3. class UDPReader implements Runnable {
    ...
    }
    

    然后实例化一个这样的线程:

    Thread t = new Thread(new UDPReader());
    
    1. 作为一项规则,如果一个线程失败,它就会终止......一个失败的线程&#34;重新创建&#34;看起来不太好。本身。更好的解决方案是提供Thread.UncaughtExceptionHandler,并在创建线程的代码中分析失败的条件,并在需要时重新启动线程。
    2. 一般来说,不要搞砸,在并发编程中你必须清楚地区分线程的逻辑和管理这个线程的外部逻辑(它的启动/中断/终止)。我想,这是你在代码中没有做到的。

答案 1 :(得分:0)

我说从同一个线程内部重启线程是一个非常糟糕的设计。

如果您需要一位主管&#39;那么你最有可能创建另一个主管&#39;将创建并启动“工作人员”的线程。每当它发现&#39; worker&#39;线程已关闭。

答案 2 :(得分:0)

您应该注意的一件事是,当您在Java中捕获异常时,程序(或线程)不会终止,除非您也告诉它。

因此,如果您在导致它发生的命令中完全捕获了异常 - 在循环内 - 您将不需要运行另一个线程。你的线程还活着并将继续循环。所有你需要做的事情 - 在catch块内 - 解决问题,以便下一个循环可以像往常一样继续 - 关闭并重新打开流,清除部分填充的数据结构,这样的东西。

当然,如果发生进一步的不可恢复的异常,你应该确实停止你的线程。