2012-09-07 241 views
2

我有兩臺linux機器。在一臺機器上,我使用一個啓動可執行文件的線程,另一個內部線程從可執行文件讀取數據,並使用可執行文件中的值填充數據庫,我使用myBatis來保存數據。之後它會不斷檢查進程和內部線程是否已啓動並正在運行。在另一臺機器上,我有遠程連接的數據庫,每晚都會連續部署數據庫,因此數據庫將被丟棄並重新創建。因此,數據庫表在此過程中不可用,例外情況如下:線程和異常處理

org.apache.ibatis.exceptions.PersistenceException 
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 
Table 'updates_table' doesn't exist 

被拋出。然後連續檢查進程和內部線程的線程被終止並停止檢查。

任何人都可以幫助我如何處理未被殺死的線程,一旦數據庫可用並運行它應該嘗試重新填充表。當數據庫不可用時,它應該一直保持嘗試,直到數據庫可用。

謝謝。

回答

1

考慮切換到您從線程作業提交到一個Executor拉東西離過程的系統:

public class MyThread extends Thread { 
    private final InputStream processStream; 
    private final Executor executor = Executors.newSingleThreadExecutor(); 

    public MyThread(InputStream processStream) { 
     this.processStream = processStream; 
    } 

    @Override 
    public void run() { 
     while ([processStream has stuff]) { 
      final Object obj = // Get your object from the stream 
      executor.execute(new Runnable() { 
       @Override 
       public void run() { 
        // Do database stuff with obj 
       } 
      }); 
     } 
    } 

    private static Object getSomethingFromStream(InputStream stream) { 
     // return something off the stream 
    } 
} 

如果異常是由您Runnable拋出,將被記錄,但它贏得不會停下來,它會繼續到隊列中的下一個工作。另外請注意,這是使用單線程執行程序,因此提交的所有內容都將一次執行一個,並按提交的順序執行。如果您想要併發執行,請使用Executors.newFixedThreadPool(int)Executors.newCachedThreadPool()。請注意,這回答瞭如何保持你的線程活着。如果你想重新提交一個可運行的重新執行作業失敗時,其run方法更改爲:

@Override 
public void run() { 
    try { 
     // Do database stuff with obj 
    } catch (PeristenceException ex) { 
     // Try again 
     executor.execute(this); 
    } 
} 

你可以把它添加邏輯裁縫何時會出現異常再試一次。

0

在高層次上,您可以使用Observable模式(內置於JDK中),以便在維護期間通知您的代碼。您可以通過產生新線程來重新建立連接。

0

使用此結構:

try{ // code to update db
} catch(MySQLSyntaxErrorException exception){ // handle db exception }

你的線程運行與DB工作中。