1

考虑以下我为测试非原始变量 ( myObject) 的锁定而编写的类。如果所有线程都在同一个对象实例上工作SynchronizationTest,我的问题是:

我知道如果 thread1 正在执行set(...)方法,那么任何其他线程(比如说 thread2)都可以执行anotherSetWithSynchronized(...)anotherSetWithoutSynchronized(...).

  1. 如果thread1SynchronizationTest在执行时锁定了对象set(...),是否意味着它已经获得了所有成员对象变量的锁定?就像在这种情况下myObject。如果没有那么,

  2. 如果thread1正在执行set(...),thread2可以同时执行anotherSetWithSynchronized(...)吗?

  3. 这两种方法都不能由线程同时执行吗?

  4. 这个设计错了吗?我是否需要明确锁定方法myObjectsynchronized set(...)像这样:

    public synchronized void set(MyValue myValue) {
        synchronized (myObject) {
            myObject.put(myValue);
        }
    } 
    

这是我的代码:

public class SynchronizationTest {
  private MyObject myObject = new MyObject();

  public synchronized void set(MyValue myValue) {
    myObject.put(myValue);
  }

  public void anotherSetWithSynchronized(MyValue myValue) {
    synchronized (myObject) {
      myObject.put(myValue);
    }
  }

  public void anotherSetWithoutSynchronized(MyValue myValue) {
    myObject.put(myValue);
  }
}
4

3 回答 3

6

1:不,set(...) 方法由“SynchronizationTest”对象的锁保护。

2:是的,他们的守卫对象和你设计的不一样。

3:一个线程每次只能运行一种方法。如果您的意思是两个线程,正如我所解释的,这些方法由两个对象保护,因此它们可以同时执行

4:是的,你是对的。


Java中的内在锁在《Java并发实战》一书中有如下描述:

同步块有两部分:对将用作锁的对象的引用,以及由该锁保护的代码块。同步方法是跨越整个方法体的同步块的简写,其锁是调用该方法的对象。(静态同步方法使用 Class 对象作为锁。)


更详细的可以参考《Java并发实战》2.3.1小节。

于 2012-05-21T07:30:27.230 回答
0

对象上的线程锁定是否也确保成员对象上的锁定?

不。

我知道如果 thread1 正在执行 set(...) 方法,那么任何其他线程(可以说 thread2)都可以执行 anotherSetWithSynchronized 中的任何一个

是的,除非 myObject 具有与“this”相同的值。

于 2012-05-21T07:14:38.223 回答
0

同步方法等价于

public void method(){
   synchronized(this){
      //something
   } 
}

1) 没有

同步仅针对指定对象,而不针对其成员。

2) 没有

3) 是的,他们不能,只有一个线程可以在给定监视器保护的同步部分内活动

4)您不需要(如果您使用显式同步,则不应在方法级别使用同步)。但它更好(对于库/大型代码库),因为这样您就可以控制谁可以访问发生同步的实例,因此其他人无法对其进行同步并导致死锁。

于 2012-05-21T07:19:31.417 回答