public class ObjectCounter {
private static long numOfInstances = 0;
public ObjectCounter(){
synchronized(this){
numOfInstances++;
}
}
**public static synchronized long getCount(){
return numOfInstances;
}**
//vs//
**public static long getCount(){
return numOfInstances;
}**
}
如果我运行几个线程,其中一些调用静态函数getCount()
,而另一些创建新实例。我希望在每次调用getCount()
时获得实时的实例数量。
- 代码中的这两个选项有什么区别吗?
- 如果我锁定“
this
”,那么难道不应该意味着在构造函数退出同步块之前无法调用getCount()
(假设我没有在getCount()
上写同步)。 - 如果我在代码的某个地方执行同步块,它是否只锁定同步块或所有“
this
”代码? - 从这里开始编辑:谢谢大家,非常有帮助,但根据你们的答案我还有一些问题。
- 如果我理解正确,synchronized(this)块不会影响(或连接到)静态同步函数(在锁定术语中不是numOfInstances增量)吗?
- 是否有更好的选择使增量和getCount()函数线程安全?(例如打开一个静态对象并执行synchronized(obj)而不是synchronized(this) - 朋友建议)。
- 如果ObjectCounter类中有一个f1()方法(非静态),当一个线程在synchronized(this)中时,其他线程能进入f1()块(不是同步类或具有同步块内部)吗?
- 如果ObjectCounter中有一个f1()方法(非静态)和f2()方法(非静态),在f1()中我有一个synchronized(this)块。当一个线程在synchronized(this)块中时,另一个线程能进入f1()块(不是同步类或具有同步块内部)吗?(假设这两个线程“工作”在同一实例上)
getCount()
)。这甚至只有在构造函数将this
发布到另一个线程时才可能发生(也称为“从构造函数中泄漏 this”)。如果您认为必须在构造函数内编写synchronized(this)
,那么您可能正在犯一个巨大的错误。 - Solomon Slow