2016-09-20 30 views
3

我正在使用Java實現後端服務。我選擇應用Singleton模式,因爲應該只有一個服務正在運行。然而,這個服務也是一個Socket.IO客戶端,因此當服務器推送時必須有某種事件被觸發。但是該事件應該是隊列中的​​。設計模式:如何在Java中以單例模式創建同步方法或塊?

我認爲我的實施不正確。 Tt似乎synchronized(this)塊不是保護Backend對象,而是Emitter.Listener對象。

private static synchronized BackendServer getInstance() 
{ 
    if(instance == null) { 
     instance = new BackendServer(); 
     try { 
      socket = IO.socket(host_name+":"+port_frontend); 
      socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { 
       @Override 
       public void call(Object... args) { 
       } 
      }).on("event1", new Emitter.Listener() { 
       @Override 
       public void call(Object... args) { 
        try { 
         synchronized(this) { <--Which object is synchronized? 
          String timestamp = getCurrentTime(); 
          String logging = "["+timestamp+"] "; 
+0

不應該使用'BackendServer'的實例方法創建套接字嗎?如果它是服務器,那麼風格明智的是你不應該單獨創建套接字。 – RealSkeptic

回答

3

在你引用行,this確實是指Emitter.Listener實例。因此,您正在創建一個使用新的Emitter.Listener實例作爲監視器的同步塊。這可能不是你想要的。如果你想同步另一個對象,你可以把它放到你的同步塊中。

作爲一個方面的說明,請注意,同步塊不會保護對象。它們確保同步塊(或具有相同監視器的任何其他同步塊)不會同時被不同的線程所支持。如果同一個對象有其他非同步代碼,可以同時執行。

+0

@RealSkeptic。對。我錯過了,謝謝。我會編輯答案。 – Hoopje

+0

嗨,感謝您的回覆。我確實想在BackendServer對象上進行同步。你能告訴我一些關於如何在Emitter.Listener函數內部實現的代碼嗎? – loudking