2017-09-26 82 views
0

我有一個來自外部API的類,我想創建一個實例並從不同線程訪問該對象的方法。我的問題在以下代碼中註釋:使用外部API對象的java中的線程安全

import java.util.concurrent.Executors; 

public class ThreadSafetyQuestion { 


    static class ExternalAPIObject { 
     void method(){ 

     } 
    } 

    private static volatile ExternalAPIObject obj; 

    static synchronized ExternalAPIObject syncGetObject(){ 
     return obj; 
    } 

    public static void main(String[] args) { 
     Executors.newSingleThreadExecutor().submit(()-> { 
      ThreadSafetyQuestion.syncGetObject().method();//Is this thread safe? 

      ExternalAPIObject externalAPIObject = ThreadSafetyQuestion.syncGetObject(); 
      //do some other stuff 
      externalAPIObject.method();//I doubt this is thread safe. How can I access this method from multiple threads in a safe way? 
     }); 
    } 
} 

回答

3

您正在從錯誤的角度看待此問題。線程安全意味着:當多個線程調用這些方法時,什麼都不會發生不好。它非常簡單:當method()沒有任何形式的同步操作「內部數據」時,則在同一對象上有多個線程調用method()可能會導致問題。

因此:您提出的所有問題都無關緊要!

唯一重要的事情:什麼究竟做這些方法是被調用?換句話說:在不同的線程中放置一個單例來調用方法沒有意義。或使物體參考易變。所有這些想法添加關於使事情「線程安全」的問題。因爲你仍然允許通過不同的線程在相同的對象上調用method()

你需要做的是:謹慎檢查你正在調用的方法究竟在做什麼。

而如果你不想去那裏:然後創建一個簡單的代表呼叫method()一個單 - 但有其方法標記爲​​。

所以:如果你不知道外部API事情 - 那麼一個保守的做法是確保始終所有的方法順序。當然,這可能會以非常消極的方式影響性能。

長話短說:看起來你缺少基本瞭解Java中的多線程概念。不要去嘗試/錯誤 - 而是退後一步深入研究這個話題!嚴重:多線程錯誤是微妙的,他們經常被忽視幾天或幾個月。避免它們的第一步:知道自己在做什麼(而不是將某些關鍵字放在某個問題上,而您不知何故閱讀了這個或那個效果)。

+0

所以你說我必須在同步包裝方法中包裝ExternalAPIObject的每個單獨的方法?呃..好的,我會聽取你的建議,並就這個話題進行更多的研究。 – dQw4w9WyXcQ