2017-09-26 86 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