Java 同步访问的方法是否应该同步?
我想从Java 同步访问的方法是否应该同步?,java,concurrency,synchronized,synchronized-block,Java,Concurrency,Synchronized,Synchronized Block,我想从synchronized块中访问一个方法。以下是一个例子: public void doSomething() { // simple stuff // a block to reduce the synchronized code to // what really needs to be synchronized. synchronized(this) { if (precondition) { doSequen
synchronized
块中访问一个方法。以下是一个例子:
public void doSomething() {
// simple stuff
// a block to reduce the synchronized code to
// what really needs to be synchronized.
synchronized(this) {
if (precondition) {
doSequentialStuff();
}
}
}
private void doSequentialStuff() {
// do stuff needs to be performed sequentially.
}
为了编写干净的代码,我想知道让方法doSequentialStuff
显式地同步是否好。IMHO这在语义上没有区别,因为锁在这两种情况下都是this
,并且该方法保证只能从synchronized
块访问。我希望增加可读性
有什么建议吗
编辑:
我修改了示例以合并注释。最好使用断言来检查锁是否被持有。注意,您确实需要启用断言才能执行检查
assert Thread.holdsLock(this);
通常,如果您使用这种私有方法,它倾向于指示您应该将类分成两部分。外层负责锁定,可能还有其他适合客户端的事情,而深层则更关注实现
使用此
进行锁定是可疑的。通常,最好使用私有显式锁对象。最好使用断言来检查锁是否被持有。注意,您确实需要启用断言才能执行检查
assert Thread.holdsLock(this);
通常,如果您使用这种私有方法,它倾向于指示您应该将类分成两部分。外层负责锁定,可能还有其他适合客户端的事情,而深层则更关注实现
使用此
进行锁定是可疑的。一般来说,最好使用私有显式锁对象。看一看,它包含了类似的模式(以singleton为例,但您可以轻松地为您的案例改装)。看一看,它包含了类似的模式(以singleton为例,但您可以轻松地为您的案例改装)。代码的可读性只能通过什么方式来提高。如果没有合法的代码路径可以在不持有锁的情况下执行doHeavyStuff
,那么一定要让它同步化,以防止不小心的开发人员将来引入的任何错误。代码的可读性只能以何种方式提高。此外,如果您使用类中其他代码的方法,您还可以确保不会忘记synchronized
块。我会很清楚地把它放在方法中。旁注:同步和“沉重的东西”通常不能很好地结合在一起…@Mat:你说得对:这是一个经典的检查而不是动作问题。我改变了这个例子。@assylias:事实上,生产代码是按顺序进行的,并不繁重。但你能解释一下——简而言之——为什么同步和“重东西”常常不能很好地结合在一起吗?@scheffield同步块是按顺序执行的——如果你在里面做的事情需要时间,这很快就会成为一个瓶颈,线程将花费大量时间等待监视器。一般来说,您希望使synchronized部分尽可能小。此外,如果您从类中的另一个代码中使用方法,则确保不会忘记synchronized
块。我会很清楚地把它放在方法中。旁注:同步和“沉重的东西”通常不能很好地结合在一起…@Mat:你说得对:这是一个经典的检查而不是动作问题。我改变了这个例子。@assylias:事实上,生产代码是按顺序进行的,并不繁重。但你能解释一下——简而言之——为什么同步和“重东西”常常不能很好地结合在一起吗?@scheffield同步块是按顺序执行的——如果你在里面做的事情需要时间,这很快就会成为一个瓶颈,线程将花费大量时间等待监视器。一般来说,您希望使synchronized部分尽可能小。不,该链接是专门关于双重检查锁定的。正确,但本文中的抽象类得到了方法invalid(X value)
,这与OP的情况类似,并且易于修改。不过我已经澄清了我的答案。要点:如果前提条件不依赖于受锁保护的状态(并由doHeavyStuff
进行了变异),那么双重检查的习惯用法是多余的。不,链接是专门关于双重检查锁定的。正确,但本文中的抽象类的方法无效(X值)
这与OP的情况类似,很容易修改。不过我已经澄清了我的答案。要点:如果前提条件不依赖于锁保护的状态(并由doHeavyStuff
突变),那么重复检查的习惯用法是多余的。