Java synchronized(Object obj)真正阻止了什么?

时间:2014-12-24 14:21:05

标签: java multithreading synchronization

假设我们有以下课程

class Class1 {

    public void Method1() {
        synchronized(myobject) {
            /* some code */
        }
    }
}

其中myobject是类的实例

class myClass {

     public void Method2() {
        synchronized(someOtherObj) {
            /* some code */
        }
     }

     public synchronized void Method3() {
        /* some code without synchronized blocks */
     }

     public void Method4() {
        /* some code without synchronized blocks */
     }
}

请帮助我了解myobject的哪些代码块仅适用于方法Method1的方法。

3 个答案:

答案 0 :(得分:1)

有两种方法可以同步某些内容。您可以使方法同步:

public synchronized void doSomething() { 
    // safe to do stuff
}

或者您可以在对象上进行同步:

synchronize( object ) {
    // safe to do stuff
}

在您的示例中,Class1.Method1和myClass.Method3以及myClass.Method4将相互阻塞。 myClass.Method2正在锁定someOtherObject,它不会影响示例中的任何内容。

可能令人困惑的是,当您将synchronized关键字添加到方法时,它实际上只是锁定'this'引用。

public synchronized void method() { }

与:

相同
public void method() {
    synchronized( this ) {
         // this may help clarify
    }
}

这就是你得到的全部。当对象同步时,任何其他线程中的任何其他对象都无法访问它们。这些东西很难做到。我推荐以下书:

实践中的Java并发 作者:Brian Goetz等。 链接:http://amzn.com/0321349601

答案 1 :(得分:0)

请帮助我了解myobject的哪些代码块仅适用于方法Method1的方法。

我认为你有向后同步。没有其他线程可以执行Class1#Method1()内的块,除非它保持myobject“锁定”。 myClass的实际方法不受影响。任何线程中的任何方法都可以调用myobject的方法,如果它们有引用的话。 (由于myClass中的方法也是同步的,它们也可能会阻塞,但这是一个单独的问题。)

出于这个原因,重要的是始终将您锁定的对象设为私有,而不是通过在任何公共方法中返回它来发布引用。

答案 2 :(得分:0)

你需要知道

void synchronized myfunc() 

是简称:

void myfunc() {
  synchronized (this) {
  }
}

其中this是从外部调用的类的当前实例。

因此,如果您有以下设置:

final MyClass a = new MyClass();

// Thread 1:
a.myfunc();

// Thread 2:
a.myfunc();

然后两个线程将等待相同的对象(即实例a)。

但是在以下设置中:

final MyClass a = new MyClass();
final MyClass b = new MyClass();

// Thread 1:
a.myfunc();

// Thread 2:
b.myfunc();

两个线程可以同时访问myfunc,因为它们在不同的对象上同步(线程1的实例a和线程2的实例b)。

如果您按以下方式编写代码:

final Object a = new Object();
final Object b = new Object();

static void myfunc() {}

// Thread 1:
synchronized(a) {
  myfunc();
}

// Thread 2:
synchronized(b) {
  myfunc();
}

这将完全相同(考虑阻塞),因为 - 如上所述 - 同步方法只是synchronized(this)的简写表达式。