2012-09-02 53 views
3

我寫了檢查通過發送小串每隔一秒套接字連接到服務器的線程類。的Java調用線程()

begin()方法執行該線程。

連接丟失後,線程嘗試重新連接。

我的問題是,如果可以通過begin()重新運行run()方法中的線程,就像我一樣(請參閱下文)。

public void begin() { 
    Check = new Thread(this); 
    Check.start(); 
} 

@Override 
public void run() { 
    Thread thisThread = Thread.currentThread(); 
    while (Check==thisThread) { 
     try { 
     oos.writeObject("a"); 
     // oos.flush(); 

     synchronized (this) { 
      while (pleaseWait) { 
       try { 
        System.out.println("waiting");  
        wait(); 
        System.out.println("not waiting");  
       } 
       catch (Exception e) { 
        System.err.println("Thread is interrupted: "+e.getMessage()); 
       } 
      } 
     } 
     sleep(1000); 
     } catch (Exception ex) { 
       v = new Visual("The connection is lost. The system will try to reconnect now."); 
       this.end(); 
       try { 
       Server=ClientLogin.checkingServers(); //returns the reachable server string address 
       socket = new Socket(Server, ServerPort); 
       System.out.println("Connected: " + socket); 
       oos = new ObjectOutputStream(socket.getOutputStream()); 
       begin(); 
       v = new Visual("The system is reconnected."); 
       } 
       catch(UnknownHostException uhe){ 
       System.out.println("Host unknown: " + uhe.getMessage()); 
       v = new Visual("The system has failed to reconnected."); 
       } 
       catch (IOException ioe) { 
       System.out.println("The system cannot connect to servers: " + ioe.getMessage()); 
       v = new Visual("The system has failed to reconnected."); 
       } 
       catch (Exception e) { 
       System.out.println("The system has failed to reconnect: " + e.getMessage()); 
       v = new Visual("The system has failed to reconnected."); 
       } 
      } 
    } 
} 

public void end() { 
    Check = null; 
} 
+0

你是不是覆蓋檢查的奔跑...... – Rolice

+0

但它完成 – Onca

回答

2

我不知道任何理由,不會工作,但它看起來有點凌亂。您可能必須聲明Checkvolatile以確保循環始終讀取當前值,以便新線程覆蓋該值。

恕我直言,更好的方法將是一個單獨的「主管」線程,負責啓動其中一個線程,然後使用Thread.join()等待它死亡,此時它可以再次啓動它。

通過這種方式,您的主線程的邏輯可以專注於它的假設要做的事情,而不需要有任何「自我意識」。

+0

之後我同意。它正在工作的任何情況。 – Onca

1

首先,代碼不是線程安全的。 「檢查」字段由一個線程寫入,但由另一個線程讀取,但不同步。不能保證新啓動的線程會看到更新後的「檢查」值,即當檢查「Check == thisThread」並執行錯誤操作時,新線程將獲得舊線程的引用,

這個可以通過使「檢查」字段變得不穩定來解決特定的問題。它確保何時更新,每個線程都會看到新的值。

這不是「錯誤」來稱呼「開始()」中的run()方法。不過我不會推薦它,因爲你在這裏有效地創建了遞歸調用。你很有可能會錯誤地陷入無限循環。嘗試下面的簡單設計。它使用while循環而不是遞歸。

package com.thinkinginobjects; 

public class HeathChecker { 

public void run() { 
    while (true) { 
     boolean success = checkHeath(); 
     if (!success) { 
      //log and re-establish connection 
     } else { 
      Thread.sleep(1000); 
     } 
    } 
} 

private boolean checkHeath() { 
    try { 
     oos.writeObject("a"); 
     return true; 
    } catch (Exception ex) { 
     return false; 
    } 
} 

}