如果我在同一个类上同步了两个方法,它们能在同一个对象上同时运行吗?例如:
class A {
public synchronized void methodA() {
//method A
}
public synchronized void methodB() {
// method B
}
}
我知道我不能在两个不同的线程中对同一个对象运行methodA()
两次。在methodB()
中也是如此。
但是,当methodA()
仍在运行时,我可以在不同的线程上运行methodB()
吗?(同一对象)
发布于 2013-03-16 01:36:34
这两种方法锁定相同的监视器。因此,您不能从不同的线程同时在同一对象上执行它们(两个方法中的一个会阻塞,直到另一个完成为止)。
发布于 2013-03-16 01:39:24
在本例中,methodA和methodB是实例方法(与静态方法相对)。将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
}
}
}
其中,同步块语法允许指定执行线程需要获取其上的固有锁以进入块的特定对象。
需要理解的重要一点是,尽管我们将“同步”关键字放在单个方法上,但核心概念是幕后的内在锁。
下面是the Java tutorial对这种关系的描述:
同步是围绕称为固有锁或监视器锁的内部实体构建的。( API规范通常将此实体简称为“监视器”。)内部锁在同步的两个方面都起着作用:强制独占访问对象的状态和建立对可见性至关重要的发生前关系。
每个对象都有一个关联的内在锁。按照惯例,需要独占和一致访问对象字段的线程必须在访问对象字段之前获取对象的固有锁,然后在使用完它们后释放固有锁。线程在获得锁和释放锁之间拥有固有锁。只要一个线程拥有一个内部锁,其他线程就不能获得相同的锁。当另一个线程试图获取锁时,它将阻塞。
锁定的目的是保护共享数据。只有当每个锁保护不同的数据成员时,才会使用上面的示例代码中所示的单独锁。
发布于 2013-03-16 01:47:10
Java Thread在进入实例同步java方法时获取对象级锁,在进入静态同步java方法时获取类级别锁。
在您的示例中,这些方法(实例)属于同一个类。因此,每当线程进入java同步方法或块时,它都会获得一个锁(调用该方法的对象)。因此,在完成第一个方法并释放lock(on object)之前,不能在同一对象上同时调用其他方法。
https://stackoverflow.com/questions/15438727
复制相似问题