在String.class上同步



在我现有的一个Spring Java代码中,有人写了如下代码:我不知道为什么我们需要同步线程安全的字符串类。有人能提出建议吗?

public class MyTimerTask extends TimerTask{

@Autowired 
MyService service;

public void run(){
synchronized(String.class){
service.callSomeMethod();
}
}   

}

没有需要使用String.class。您可以同步任何对象,包括任何Class实例。使用String类是一个糟糕的选择,但它会工作。

这是一个糟糕的选择的原因是(a)它是public-你的代码可能以意想不到的方式与其他程序员也决定编写synchronized(String.class)的大型程序的其他部分进行交互-但更重要的是(b)它完全是疯狂的。这会让其他程序员浪费时间去理解你做了什么,以及为什么你认为这样做是明智的。

可能还有第三个原因(c),但如果没有看到更多的代码,很难判断。原因(c)是String.class是一个static实例,如果你使用一个全局对象来同步许多不同的MyTimerTask实例,如果这些实例不通过共享的static变量相互交互,那么使用一个全局同步对象可能会增加一个不必要的性能瓶颈。

这样会更好(考虑到原因(a)和(b)):

public class MyTimerTask extends TimerTask{
private final static Object mutex = new Object();
...
public void run(){    
synchronized(mutex){
service.callSomeMethod();
}    
}   
}

或者,根据MyTimerTask的使用方式,从mutex的声明中删除static可能更好(照顾原因(c))。