19

我对 Java Synchronization 有疑问。我想知道我的类中是否有三个同步方法,并且一个线程在一个同步方法中获得锁定,另外两个将被锁定?我问这个问题是因为我对以下陈述感到困惑。

当线程位于对象的同步方法中时,所有其他希望执行此同步方法或对象的任何其他同步方法的线程都必须等待。此限制不适用于已经拥有锁并正在执行对象的同步方法的线程。这样的方法可以调用对象的其他同步方法而不会被阻塞。对象的非同步方法当然可以随时被任何线程调用

4

8 回答 8

18

Java 中的同步是通过在某些特定对象上获取监视器来完成的。因此,如果您这样做:

class TestClass {
    SomeClass someVariable;

    public void myMethod () {
        synchronized (someVariable) {
            ...
        }
    }

    public void myOtherMethod() {
        synchronized (someVariable) {
            ...
        }
    }
}

然后,这两个块将在不被修改的情况下随时通过执行 2 个不同的线程来保护someVariable。基本上,据说这两个块与变量同步someVariable

当你把synchronized方法放在上面的时候,它基本上和 的意思是一样的synchronized (this),也就是在执行这个方法的对象上进行同步。

那是:

public synchronized void myMethod() {
    ...
}

意思相同:

public void myMethod() {
    synchronized (this) {
       ...
    }
}

因此,要回答您的问题 - 是的,线程将无法在不同的线程中同时调用这些方法,因为它们都持有对同一监视器的引用,即this对象的监视器。

于 2012-06-25T06:59:49.890 回答
1

是的。
执行同步方法线程需要获取对象锁,并且一次只有一个线程可以获取对象锁。

于 2012-06-25T06:55:10.543 回答
0

每个 java 对象(类实例)都有一个互斥对象。方法前面的 synchronized 关键字意味着正在运行的线程必须获取该对象的互斥锁。实际上,

public synchronized doSomething(){
   ...
}

与此完全相同:

public  doSomething(){
   synchronized(this){
      ...
   }
}

所以是的,每个类实例只有一个线程执行同步方法。

请注意,有时这可能不是最理想的,因为您想保护修改,但对并发读取很好,在这种情况下,您可能需要查看ReadWriteLock而不是 synchronized 关键字。

于 2012-06-25T06:56:17.590 回答
0

好吧,每个对象只有一个锁。并且所有同步方法都被此锁锁定。因此,无论哪个线程一次获得锁,它都被授权通过所有同步方法。但是等待锁的线程在获得锁之前不能进入同步方法。

因此,一次只有线程规则和其他规则必须等待进入任何同步方法,无论统治线程是否正在执行该方法。

于 2012-06-25T06:59:38.780 回答
0

是的,除了获得锁的线程之外的所有线程都必须等到锁再次被释放才能执行三种同步方法之一。

请记住,同步方法与普通方法相同

synchronized(this) {
    // method body
} 
于 2012-06-25T07:00:06.753 回答
0

这是真的,而且是这样的。也有必要使该对象的数据保持一致。

假设不存在此验证,并且有一个变量 x 正在由 2 个不同的同步方法 xxx() 和 yyy() 操作。

因此,如果线程 A 获得方法 xxx() 的锁定,该方法正在操作 x=5,第二个线程 B 获得方法 yyy() 的锁定并操作 x=-5,那么在方法 xxx() 结束时,线程 A 期望 x=5但它会得到 x=0 这是错误的。

这就是它以这种方式实现的原因。

于 2012-06-25T07:01:50.903 回答
0

如果一个类有 4 个同步方法,那么是的,一次只有一个线程可以访问这些方法。我想这里的疑问是,每个线程可以一次访问单个类实例的不同同步方法。答案是不。一次只有一个线程可以访问同步方法。

于 2017-02-08T20:29:33.047 回答
-1

我不确定您会感到困惑,但是获取锁会阻止其他线程在您持有它时获取它,并且类的所有非静态同步方法在同一个对象上同步,所以您的问题的答案是'是的',假设我已经正确理解了你。我不知道“同步”还有什么意思,或者它对任何其他含义有什么用处。

于 2012-06-25T06:56:25.257 回答