当前位置: 首页 > 知识库问答 >
问题:

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

卢磊
2023-03-14

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

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

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

我知道我不能在两个不同的线程中对同一个对象运行method A()两次。

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

共有3个答案

田志尚
2023-03-14

Java线程在进入实例同步Java方法时获取对象级锁,在进入静态同步Java方法时获取类级锁。

在您的例子中,方法(实例)属于同一类。因此,当线程进入java同步方法或块时,它会获得一个锁(调用该方法的对象)。因此,在完成第一个方法并释放锁(对象上的锁)之前,不能在同一对象上同时调用其他方法。

濮冠宇
2023-03-14

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

如果有两个不同的实例方法标记为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
        }
    }
}

其中,同步块语法允许指定特定对象,执行线程需要获取该对象的内部锁才能进入块。

需要理解的重要一点是,即使我们在单个方法上放置了一个“同步”的关键字,但核心概念是幕后的内在锁。

以下是Java教程如何描述这种关系:

同步是围绕称为内在锁或监视锁的内部实体构建的。(API规范通常将该实体简单地称为“监视器”)内在锁在同步的两个方面都起作用:强制对对象状态的独占访问,以及在对可见性至关重要的关系之前建立。

每个对象都有一个与之关联的内在锁。按照惯例,需要以独占和一致方式访问对象字段的线程必须在访问对象字段之前获取对象的固有锁,然后在处理完这些字段后释放固有锁。线程在获取锁和释放锁之间拥有内在锁。只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁。另一个线程在尝试获取锁时将阻塞。

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

闾丘京
2023-03-14

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

 类似资料:
  • 问题内容: public class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void b

  • 问题内容: 我有4种方法(,,和一类)。方法,并有方法。另外,我有4个线程,,和分别。 如果访问方法(同步方法),线程访问方法(同步方法)是否可以同时进行?如果不是,则t2的状态如何? 问题答案: 如果t1访问m1方法(同步方法),t2线程可以同时访问m2方法(同步方法)吗? 该关键字适用于 目标水平 ,且只有一个线程可持有对象的锁。因此,只要您在谈论同一个对象,那么 否 ,它将等待释放进入时获得

  • 问题内容: 我想知道如果在同一个对象上同步两次,在Java中是否会出现任何奇怪的行为? 场景如下 两种方法都使用该对象并对其进行同步。当第一个方法调用第二个方法时,它会被锁定而停止吗? 我不这么认为,因为它是同一个线程,但是我不确定是否可能会出现其他任何奇怪的结果。 问题答案: 同步块使用 可重入 锁,这意味着如果线程已经持有该锁,则它可以重新获取它而不会出现问题。因此,您的代码将按预期工作。 请

  • 假设我们有两个类A、B和各自类的同步方法methodA、methodB。如果我们从synchronizedmethodA调用synchronized methodB,那么当methodB仍在执行时,线程是否仍对ObjectA保持锁定?

  • 问题内容: 我面临有关Java方法同步的问题。希望我能简要解释一下: 我在两个不同的类中,在两个不同的包中有两个不同的方法。就像是: 好的,所以现在我需要同步这两个 不是thread的方法 。到目前为止,我有两种不同的方法: 共享信号量 。 在和外部创建一个共享的静态信号量,例如: 无论如何,我真的不知道JVM是否会将其视为共享信号量。 已同步(SharedClass.class) 。 使用共享类

  • 问题内容: 我想使用rsync 在两个方向上 同步 两个目录。 我指的是经典意义上的同步( 不是 rsync手册中的含义): 我想 双向 更新目录,具体取决于哪个 更新 。 可以通过rsync (在Linux方式中更可取) 完成此操作吗? 如果没有,还有哪些其他解决方案? 问题答案: 只需使用“较新”模式(-u或– update标志)加上-t(复制文件修改时间),-r(用于递归文件夹)和-v(用于

  • 问题内容: 我刚刚发现我可以使用Python编写一个非常简单的Web服务器。我已经有一个Apache Web服务器,我想在这台机器上尝试基于Python的Web服务器。但是,如果尝试尝试,可能会引起某种冲突。我的意思是两个Web服务器将如何“决定”谁需要服务器处理来自客户端的请求? 问题答案: 让他们监听不同的端口,您会没事的。 默认的Web端口是80。当您在浏览器中打开某些网址而不指定端口时,默