关于从同步块调用方法

shi*_*zou 5 java multithreading synchronization thread-safety java-8

同步一个方法是否相当于只让一个线程来评估它,直到它超出范围(包括内部方法调用)?

例如:

public synchronized void foo(){

    if(critical condition){
        bar();  // can influence the above condition
    }
    baz(); // can influence the above condition
}
Run Code Online (Sandbox Code Playgroud)

可以有两个线程bar(假设仅从这里调用)吗?

如果baz可以从代码中除 之外的其他地方调用怎么办foo,那么里面可以有两个线程吗?

Pet*_*rey 5

bar 中可以有两个线程吗(假设仅从这里调用它)?

是的,只要他们使用不同的对象,或者其中一个对象正在wait()使用。

如果可以从代码中除 foo 之外的其他地方调用 baz,那么可以有两个线程吗?

是的,放置synchronized在一个方法上对不同步的方法没有影响。


Dan*_*iel 3

这是编写代码的等效方法:

public void foo(){
    synchronized (this) {
        if(critical condition){
            bar();  // can influence the above condition
        }
        baz(); // can influence the above condition
    }
}
Run Code Online (Sandbox Code Playgroud)

因为同步方法实际上使用this锁对象来同步它们的主体。

foo()那么,两个线程可以同时执行还是bar()同时执行呢?当然,如果他们正在执行不同对象的foo()bar()不同的对象。

此外,对 的调用baz()根本不是同步的,因此即使任何两个线程都可以baz()同时运行单个对象,只要其中至少一个线程从外部调用它foo()

这两个资源对于理解同步在 Java 中的作用和不作用非常有用:

我建议您检查这些页面,因为有些信息在您检查之前并不是太明显。例如:

  • 两个不同的线程不能同时执行单个对象的两个不同的同步方法。
  • 单个线程可以执行同一对象的两个不同的同步方法(称为可重入同步