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

时间:2021-04-23 17:36:03

If i synchronized two methods on the same class, can they run simultaneously on the same object? for example:

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

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

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

I know that I can't run methodA() twice on same object in two different threads. same thing in methodB().

我知道我不能在两个不同的线程中对同一个对象运行methodA()两次。方法B()中的相同内容。

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

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

9 个解决方案

#1


93  

Both methods lock the same monitor. Therefore, you can't simultaneously execute them on the same object from different threads (one of the two methods will block until the other is finished).

两种方法都锁定同一个监视器。因此,您不能在不同线程的同一对象上同时执行它们(两个方法中的一个将阻塞,直到另一个完成)。

#2


70  

Putting synchronized on a method means the thread has to acquire the lock on the object instance before entering that method, so if you have two different methods marked synchronized the threads entering them will be contending for the same lock, and once one thread gets the lock all other threads are shut out of all methods that synchronize on that same lock. So in order for the two methods to run concurrently they would have to use different locks, like this:

对方法进行同步意味着线程必须在进入该方法之前获取对象实例上的锁定,因此如果您有两个标记为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
        }
    }
}

#3


12  

Java Thread acquires an object level lock when it enters into an instance synchronized java method and acquires a class level lock when it enters into static synchronized java method.

Java Thread在进入实例synchronized java方法时获取对象级锁,并在进入静态同步java方法时获取类级锁。

In your case, the methods(instance) are of same class. So when ever a thread enters into java synchronized method or block it acquires a lock(the object on which the method is called). So other method cannot be called at the same time on the same object until the first method is completed and lock(on object) is released.

在您的情况下,方法(实例)属于同一类。因此,当线程进入java synchronized方法或块时,它获取一个锁(调用该方法的对象)。因此,在完成第一个方法并释放lock(on object)之前,不能在同一个对象上同时调用其他方法。

#4


7  

In your case you synchronized two method on the same instance of class. So, these two methods can't run simultaneously on different thread of the same instance of class A. But they can on different class A instances.

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

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

is the same as:

是相同的:

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

#5


5  

From oracle documentation link

从oracle文档链接

Making methods synchronized has two effects:

使方法同步有两个影响:

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

首先,不可能对同一对象上的两个同步方法的调用进行交错。当一个线程正在为对象执行同步方法时,所有其他线程都会调用同一对象的同步方法(暂停执行),直到第一个线程完成对象为止。

Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads

其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立先发生关系。这可以保证对所有线程都可以看到对象状态的更改

This will answer your question: On same object, You can't call second synchronized method when first synchronized method execution is in progress.

这将回答您的问题:在同一个对象上,当第一个同步方法执行正在进行时,您无法调用第二个同步方法。

Have a look at this documentation page to understand intrinsic locks and lock behavior.

查看此文档页面以了解内部锁定和锁定行为。

#6


3  

Just to all clarity, It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because one is having object level lock and other class level lock.

简而言之,静态同步和非静态同步方法可以同时或同时运行,因为一个具有对象级锁定和其他类级别锁定。

#7


3  

Think of your code as the below one:

将您的代码视为以下代码:

class A {

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

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

So, synchronized on method level simply means synchronized(this). if any thread runs a method of this class, it would obtain the lock before starting the execution and hold it until the execution of the method is finished.

因此,在方法级别上同步只是意味着同步(this)。如果任何线程运行此类的方法,它将在开始执行之前获取锁并保持它直到方法的执行完成。

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

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

Indeed, it is not possible!

的确,这是不可能的!

Hence, multiple threads will not able to run any number of synchronized methods on the same object simultaneously.

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

#8


0  

You are synchronizing it on object not on class. So they cant run simultaneously on the same object

您正在同步对象而不是在课堂上。所以他们不能同时在同一个对象上运行

#9


-1  

Two different Threads executing a common synchronized method on the single object, since the object is same, when one thread uses it with synchronized method, it will have to varify the lock, if the lock is enabled, this thread will go to wait state, if lock is disabled then it can access the object,while it will access it will enable the lock and will release the lock only when it's execution is complete. when the another threads arrives, it will varify the lock, since it is enabled it will wait till the first thread completes his execution and releases the lock put on the object,once the lock is released the second thread will gain access to the object and it will enable the lock untill it's execution. so the execution will not be not concurrent, both threads will execute one by one, when both the threads use the synchronized method on different objects, they will run concurrently.

两个不同的线程在单个对象上执行公共同步方法,因为对象相同,当一个线程使用同步方法时,它必须变量锁定,如果锁定被启用,该线程将进入等待状态,如果锁定被禁用,那么它可以访问该对象,而它将访问它将启用锁定,并且只有在执行完成时才会释放锁定。当另一个线程到达时,它将改变锁,因为它被启用它将等到第一个线程完成执行并释放对象的锁定,一旦锁定被释放,第二个线程将获得对象的访问权限它将启用锁定,直到它的执行。因此执行不会是并发的,两个线程将逐个执行,当两个线程在不同对象上使用synchronized方法时,它们将同时运行。

#1


93  

Both methods lock the same monitor. Therefore, you can't simultaneously execute them on the same object from different threads (one of the two methods will block until the other is finished).

两种方法都锁定同一个监视器。因此,您不能在不同线程的同一对象上同时执行它们(两个方法中的一个将阻塞,直到另一个完成)。

#2


70  

Putting synchronized on a method means the thread has to acquire the lock on the object instance before entering that method, so if you have two different methods marked synchronized the threads entering them will be contending for the same lock, and once one thread gets the lock all other threads are shut out of all methods that synchronize on that same lock. So in order for the two methods to run concurrently they would have to use different locks, like this:

对方法进行同步意味着线程必须在进入该方法之前获取对象实例上的锁定,因此如果您有两个标记为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
        }
    }
}

#3


12  

Java Thread acquires an object level lock when it enters into an instance synchronized java method and acquires a class level lock when it enters into static synchronized java method.

Java Thread在进入实例synchronized java方法时获取对象级锁,并在进入静态同步java方法时获取类级锁。

In your case, the methods(instance) are of same class. So when ever a thread enters into java synchronized method or block it acquires a lock(the object on which the method is called). So other method cannot be called at the same time on the same object until the first method is completed and lock(on object) is released.

在您的情况下,方法(实例)属于同一类。因此,当线程进入java synchronized方法或块时,它获取一个锁(调用该方法的对象)。因此,在完成第一个方法并释放lock(on object)之前,不能在同一个对象上同时调用其他方法。

#4


7  

In your case you synchronized two method on the same instance of class. So, these two methods can't run simultaneously on different thread of the same instance of class A. But they can on different class A instances.

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

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

is the same as:

是相同的:

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

#5


5  

From oracle documentation link

从oracle文档链接

Making methods synchronized has two effects:

使方法同步有两个影响:

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

首先,不可能对同一对象上的两个同步方法的调用进行交错。当一个线程正在为对象执行同步方法时,所有其他线程都会调用同一对象的同步方法(暂停执行),直到第一个线程完成对象为止。

Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads

其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立先发生关系。这可以保证对所有线程都可以看到对象状态的更改

This will answer your question: On same object, You can't call second synchronized method when first synchronized method execution is in progress.

这将回答您的问题:在同一个对象上,当第一个同步方法执行正在进行时,您无法调用第二个同步方法。

Have a look at this documentation page to understand intrinsic locks and lock behavior.

查看此文档页面以了解内部锁定和锁定行为。

#6


3  

Just to all clarity, It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because one is having object level lock and other class level lock.

简而言之,静态同步和非静态同步方法可以同时或同时运行,因为一个具有对象级锁定和其他类级别锁定。

#7


3  

Think of your code as the below one:

将您的代码视为以下代码:

class A {

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

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

So, synchronized on method level simply means synchronized(this). if any thread runs a method of this class, it would obtain the lock before starting the execution and hold it until the execution of the method is finished.

因此,在方法级别上同步只是意味着同步(this)。如果任何线程运行此类的方法,它将在开始执行之前获取锁并保持它直到方法的执行完成。

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

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

Indeed, it is not possible!

的确,这是不可能的!

Hence, multiple threads will not able to run any number of synchronized methods on the same object simultaneously.

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

#8


0  

You are synchronizing it on object not on class. So they cant run simultaneously on the same object

您正在同步对象而不是在课堂上。所以他们不能同时在同一个对象上运行

#9


-1  

Two different Threads executing a common synchronized method on the single object, since the object is same, when one thread uses it with synchronized method, it will have to varify the lock, if the lock is enabled, this thread will go to wait state, if lock is disabled then it can access the object,while it will access it will enable the lock and will release the lock only when it's execution is complete. when the another threads arrives, it will varify the lock, since it is enabled it will wait till the first thread completes his execution and releases the lock put on the object,once the lock is released the second thread will gain access to the object and it will enable the lock untill it's execution. so the execution will not be not concurrent, both threads will execute one by one, when both the threads use the synchronized method on different objects, they will run concurrently.

两个不同的线程在单个对象上执行公共同步方法,因为对象相同,当一个线程使用同步方法时,它必须变量锁定,如果锁定被启用,该线程将进入等待状态,如果锁定被禁用,那么它可以访问该对象,而它将访问它将启用锁定,并且只有在执行完成时才会释放锁定。当另一个线程到达时,它将改变锁,因为它被启用它将等到第一个线程完成执行并释放对象的锁定,一旦锁定被释放,第二个线程将获得对象的访问权限它将启用锁定,直到它的执行。因此执行不会是并发的,两个线程将逐个执行,当两个线程在不同对象上使用synchronized方法时,它们将同时运行。