有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如果我在同一个类上同步了两个方法,它们能同时运行吗?

如果我在同一个类上同步了两个方法,它们能在同一个对象上同时运行吗?例如:

class A {
    public synchronized void methodA() {
        //method A
    }

    public synchronized void methodB() {
        // method B
    }
}

我知道我不能在两个不同的线程中对同一个对象运行methodA()两次。在methodB()中也是如此

但是当methodA()仍在运行时,我可以在不同的线程上运行methodB()吗?(同一对象)


共 (3) 个答案

  1. # 1 楼答案

    在本例中,您在同一个类实例上同步了两个方法。因此,这两个方法不能同时在同一个A类实例的不同线程上运行,但它们可以在不同的A类实例上运行

    class A {
        public synchronized void methodA() {
            //method A
        }
    }
    

    与以下内容相同:

    class A {
        public void methodA() {
            synchronized(this){
                // code of method A
            }
        }
    }
    
  2. # 2 楼答案

    把你的代码想象成以下代码:

    class A {
    
    public void methodA() {
        synchronized(this){        
          //method A body
        }
    }
    
    public void methodB() {
        synchronized(this){
          // method B body
        }
    }
    

    所以,在方法级别上同步仅仅意味着同步(这一点)。 如果任何线程运行此类的方法,它将在开始执行之前获得锁,并将其保持到方法执行完成

    But can I run methodB() on different thread while methodA() is still running? (same object)

    事实上,这是不可能的

    因此,多个线程将无法在同一对象上同时运行任意数量的同步方法

  3. # 3 楼答案

    在示例中,methodA和methodB是实例方法(与静态方法相反)。将synchronized放在实例方法上意味着线程必须在调用该方法的对象实例上获取锁(“内在锁”),然后线程才能开始执行该方法中的任何代码

    如果有两个不同的实例方法标记为synchronized,并且不同的线程在同一个对象上并发调用这些方法,那么这些线程将争夺同一个锁。一旦一个线程获得了锁,所有其他线程都将被排除在该对象上的所有同步实例方法之外

    为了使这两个方法同时运行,它们必须使用不同的锁,如下所示:

    class A {
        private final Object lockA = new Object();
        private final Object lockB = new Object();
    
        public void methodA() {
            synchronized(lockA) {
                //method A
            }
        }
    
        public void methodB() {
            synchronized(lockB) {
                //method B
            }
        }
    }
    

    其中,synchronized block语法允许指定执行线程需要获取内在锁才能进入块的特定对象

    需要理解的重要一点是,尽管我们在单个方法上添加了一个“synchronized”关键字,但其核心概念是幕后的内在锁

    以下是the Java tutorial如何描述这种关系:

    Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. (The API specification often refers to this entity simply as a "monitor.") Intrinsic locks play a role in both aspects of synchronization: enforcing exclusive access to an object's state and establishing happens-before relationships that are essential to visibility.

    Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.

    锁定的目的是保护共享数据。只有当每个锁保护不同的数据成员时,才能使用上述示例代码中所示的单独锁