Java静态和线程安全,或者怎么做
我正在扩建一个图书馆为我做一些工作。代码如下:Java静态和线程安全,或者怎么做,java,thread-safety,Java,Thread Safety,我正在扩建一个图书馆为我做一些工作。代码如下: public static synchronized String decompile(String source, int flags,UintMap properties,Map<String,String> namesMap) { Decompiler.namesMap=namesMap; String decompiled=decompile(source,flags,propertie
public static synchronized String decompile(String source, int flags,UintMap properties,Map<String,String> namesMap)
{
Decompiler.namesMap=namesMap;
String decompiled=decompile(source,flags,properties);
Decompiler.namesMap=null;
return decompiled;
}
public静态同步字符串反编译(字符串源、int标志、UintMap属性、映射名称映射)
{
Decompiler.namesMap=namesMap;
字符串反编译=反编译(源、标志、属性);
反编译器.namesMap=null;
返回反编译;
}
问题在于namesMap
是静态变量。那根线安全吗?因为如果此代码同时运行,namesMap变量可能会更改。对此我能做些什么?方法反编译
是线程安全的(它永远不会同时在两个线程上运行),但是如果该方法以外的任何方法也使用名称映射
,则不,总的来说,这不是线程安全的:在不同线程上运行的反编译
以外的另一种方法可能会在反编译
方法使用映射时修改映射,可能会造成混乱。:-)
您可以查看名称空间中的类(例如),看看这些类是否适用于您正在做的事情
Edit(回应您的评论)。如果静态成员
namemap
只被反编译
使用,而不被其他任何东西使用(您没有得到对它的引用,等等),那么您就没事了。如果使用它的唯一位置是序列化的,那么它是静态的这一事实并不重要。如果在方法反编译(字符串、int、UintMap、Map)
运行时,其他线程可能会对名称映射进行更改,然后,您应该复制传入的映射,而不仅仅是分配引用
Decompiler.namesMap= new HashMap<String, String>(namesMap);
Decompiler.namesMap=newhashmap(namesMap);
如果其他线程可能会更改映射中包含的元素,而不仅仅是映射本身的结构,那么您应该确保您的decompile()
方法和使用namemap
的其他线程由相同的锁保护。实际上Decompiler.namemap=namemap代码>
是唯一设置名称映射的地方
但是在代码中没有其他地方更改名称映射。。
只读
我想确保
String decompiled=decompile(source,flags,properties);
将使用相同的名称映射。只有一个名称映射,因此您不必担心它是否会使用相同的名称映射。可能是这样。在代码的其他地方是否可以访问NameMap?如果是这样的话,你能给出一个具体的例子吗?它只能从另一个反编译()中访问。.“只使用过”意味着有一天,另一个开发人员会忘记这个隐含的需求,在其他地方使用它,你会得到虚假的错误。如果静态成员namemap
只在一个地方使用,为什么不将其从静态成员更改为方法参数?这样你就可以消除所有疑问。@matt:他必须把它存放在某个地方。:-)Java没有C的静态局部变量行为。(我并不是说它不是一件坏事,只是它不是。)@t.J.我的意思是,与其将引用存储在静态变量中,以便另一个decompile()
方法可以访问它,不如简单地更改另一个decompile()
方法以接受此映射作为参数