我有一个来自外部 API 的类,我想创建它的一个实例并从不同的线程访问该对象的方法。我的问题作为以下代码中的注释:
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?
});
}
}
最佳答案
您从错误的角度看待这个问题。线程安全意味着:当多个线程调用这些方法时,不会发生任何坏情况。这真的很简单:当 method()
确实在没有任何形式的同步的情况下操作“内部数据”时 - 那么在同一个对象上有多个线程调用 method()
就可以了导致出现问题。
因此:您在问题中提出的所有内容都不重要!
唯一重要的是:您调用的这些方法到底做什么?!换句话说:建立一个单例来调用不同线程中的方法是没有意义的。或者使对象引用易失。所有这些想法在使事物“线程安全”方面添加了零。因为您仍然允许不同线程在同一个对象上调用 method()
。
您必须做什么:仔细检查您正在调用的方法到底在做什么。
如果您不想去那里:然后创建一个单例,它只是委托(delegate)调用method()
- 但其方法标记为已同步
。
所以:如果您对外部 API 一无所知 - 那么一种保守的方法是确保始终按顺序使用其所有方法嗯>。当然,这会对性能产生非常负面的影响。
长话短说:看来您缺乏对 Java 中多线程概念的基本理解。那么就不要尝试/犯错——而是退后一步,深入研究这个主题!说真的:多线程错误很微妙,它们通常会在几天或几个月内被忽视。避免它们的第一步:知道你在做什么(而不是在你以某种方式读到的有关具有这种或那种效果的问题上抛出一些关键字)。
关于java - java 中带有外部 API 对象的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46427978/