运行 具有同步方法和普通方法的对象,并发?

Running an object with a synchronized method and normal method, concurrently?

难道只是两个synchronized方法不能运行并发吗?

例如,有人编码 2 Java 类.

public class A {
    public synchronized void a1(){   
    //do something   }
    public void a2(){
    //do something   }
    public synchronized int a3(){
    int var = 0;
    //do something changing var
    return var;   } }


public class B {

  public void b1(){
    //do something
  }


  public synchronized int b2(){   
    int var = 0;
    //do something changing var
    return var;
  }

  public void b3(){
    //do something
  }
}

有了 main 方法,

public static void main(String[] args){
  A firstA = new A();
  A secondA = new A();
  B firstB = newB();

  //create some threads that perform operations on firstA, secondA and first B and start them
}

假设它们 运行 并行并在创建的对象上调用方法,并且还假设这些方法中的 none 当前被其他机制阻止 运行ning。

在我给出的示例中的方法中,有没有 不能 运行 concurrently 如果调用同时通过 2 个不同的线程?

通过运行并发 我的意思是,它们将按顺序排列,以便一个在另一个开始之前完成。

当然,答案取决于"something"你"do"什么时候"do something",既然你不表现出来,就没人能回答了。当您省略重要信息时,就会发生这种情况。不要遗漏重要信息。

我们可以说的是 A 中的同步方法不使用与 B 中的同步方法相同的锁。

如果多个线程访问相同的数据,那么它们必须相互同步。线程之间相互同步的唯一方法是使用相同的同步手段。如果那是使用 synchronized,那么它们必须在同一个监视器(锁)上同步。因此,如果 A 方法和 B 方法从不同的线程访问相同的数据,谁能从您显示的内容中判断它们是否执行了操作?那么它们将无法正常工作。

如果任何一个非同步方法从不同的线程访问相同的数据,而你没有展示的部分没有其他有效的同步手段,那么它们将无法工作。

这一切都取决于您决定不向我们展示的内容。

他们都可以同时 运行 而不会互相打扰。 因为每个线程处理不同的实例,所以它们不需要等待同步方法。

假设不涉及其他同步,唯一会相互排除的调用是:

  1. firstA.a1() 对比 firstA.a1()
  2. firstA.a1() 对比 firstA.a3()
  3. secondA.a1() 对比 secondA.a1()
  4. secondA.a1() 对比 secondA.a3()
  5. firstB.b2() 对比 firstB.b2()

这是因为同步块必须使用相同的锁才能使它们相互影响。当您将整个方法标记为 synchronized 时,锁定对象将是 this 的值。所以 firstA 中的方法将完全独立于 secondAfirstB 中的方法,因为 它们使用不同的锁 .

您的代码中未标记 synchronized 的方法甚至根本不会尝试获取任何锁,它们可以随时 运行。

请注意,互斥只是多线程的一方面。为了让您的程序正常运行,您还必须考虑可见性和安全发布等问题。