【发布时间】:2015-07-10 13:51:26
【问题描述】:
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),那么你可能犯了一个巨大的错误。 -
在您获得正确且完整的问题答案后,请不要编辑您的问题以添加更多问题(或者,更糟糕的是,替换您现有的问题)。为此提出一个新问题,或在您的后续问题中评论正确答案。
-
所有的答案都很好而且很有帮助,但是我只能选择一个对我有帮助的,而且我认为只选择一个是不公平的。如果是必须的,我会选择一个。
标签: java multithreading synchronized java-threads synchronized-block