假设我们有以下课程
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的方法。
答案 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)
的简写表达式。