假设我们有下面的类
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 */
}
}请帮助我理解我的对象的哪些代码块仅可用于名为Method1方法的胎面。
发布于 2014-12-24 14:33:00
同步某物有两种方法。可以使方法同步:
public synchronized void doSomething() {
// safe to do stuff
}也可以对对象进行同步:
synchronize( object ) {
// safe to do stuff
}在您的示例中,Class1.Method 1与myClass.Method3和myClass.Method4将相互阻塞。myClass.Method2正在锁定someOtherObject,它不会影响示例中的任何内容。
令人困惑的是,当您将同步关键字添加到方法中时,它实际上只是锁定了“this”引用。
public synchronized void method() { }与以下相同:
public void method() {
synchronized( this ) {
// this may help clarify
}
}这就是你所得到的。当对象被同步时,其他线程中的任何其他对象都无法访问它们。这件事很难搞清楚。我推荐以下书:
Java并发在实践中由Brian等人。链接:http://amzn.com/0321349601
发布于 2014-12-24 14:52:38
帮助我理解我的对象的哪些代码块只能用于名为Method1.的方法。
我认为你的同步是反向的。没有其他线程可以在Class1#Method1()内部执行块,除非它持有myobject“锁”。myClass的实际方法不受影响。来自任何线程的任何方法都可以调用myobject的方法,如果它们有对它的引用。(由于myClass中的方法也是同步的,它们也可能阻塞,但这是一个单独的问题。)
因此,重要的是始终将锁定的对象设置为私有对象,而不是通过在任何公共方法中返回引用来发布引用。
发布于 2014-12-26 12:53:49
你得知道
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)的一个简短的表达式。
https://stackoverflow.com/questions/27638310
复制相似问题