2011-03-03 34 views
1

我有一個Java項目,作爲一個服務器。當這個項目的一個實例運行時,我可以運行另一個實例。
我該如何避免在同一個java項目上同時運行多個實例? (檢測到另一個實例時停止服務器)我該如何避免在同一個java項目上同時運行多個實例?

+5

的接受了http://stackoverflow.com/questions/920386/how-to-allow-running-only-one-instance-of答案-a-java-program-at-a-time應該爲你工作。 – 2011-03-03 13:44:56

+0

我試試這個答案它是正確的thx – 2011-03-04 10:09:51

回答

3
import java.net.ServerSocket; 
..... 
private static final int PORT = 9999; 
private static ServerSocket socket; 
public static void main(String[] args) { 

    try { 
     socket = new ServerSocket(PORT, 0, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })); 

       {/*here write your own code taht must be run in the main*/} 

    } catch (BindException e) { 
     System.err.println("**********************************Already running."); 
     System.exit(1); 
    } catch (IOException e) { 
     System.err.println("************************************Unexpected error."); 
     e.printStackTrace(); 
     System.exit(2); 
    } catch (Exception e) { 
     System.err.println("************************************ Error"); 
     System.exit(3); 
    } 
} 

我用這個代碼和它的工作嘗試

+1

+1好主意!我用這個解決方案看到的唯一問題是它不會允許不同的應用程序使用相同的端口。如果您記得爲每個應用程序分配另一個端口,那麼也可以。如果將端口保留在屬性文件中,則還可以重新配置端口並避免第三個應用程序出現問題。 – 2011-03-04 12:02:17

+0

@Costis,這可能是一個安全的假設,所討論的軟件是服務器,很有可能會在特定的端口上列出某些東西。 – vickirk 2011-03-04 15:29:00

2

最簡單的方法是使用鎖定文件,如果應用程序崩潰,則會導致問題。嘗試將pid寫入鎖定文件,您可以檢查該pid是否存在(儘管不是本地可能在包裝器shell腳本中)。

如果你正在運行服務器,你可以不檢查一個端口是否打開,或者最好還是一個已知端口上的jmx實例。

0

您可以編寫用於應用程序啓動的簡單命令行腳本 - 該檢查是服務器在實際運行新實例之前運行的。只要用wget檢查url例如...

1

我完全支持@vickirk - 他的方法允許服務器的第二個「不需要」的實例變成「休眠」而不是簡單地終止,即定期運行以執行檢查如果「活動」實例仍然實際活動/存在,並且在發生故障時接管。

在分佈式情況下,如果要求跨越多臺計算機有一個服務器實例,則該方法仍然是找到可以在物理上或邏輯上鎖定的公共資源。爲此,我個人使用一個控制數據庫表,一個活動進程寫入其PID和「心跳」,其他所有人都在檢查該「心跳」是否相當近,如果不是,則會變爲活動狀態。

相關問題