Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步访问的方法是否应该同步?_Java_Concurrency_Synchronized_Synchronized Block - Fatal编程技术网

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
突变),那么重复检查的习惯用法是多余的。