首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java同步(Object)真正阻止了什么?

Java同步(Object)真正阻止了什么?
EN

Stack Overflow用户
提问于 2014-12-24 14:21:05
回答 3查看 752关注 0票数 1

假设我们有下面的类

代码语言:javascript
复制
class Class1 {

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

其中myobject是类的实例。

代码语言:javascript
复制
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方法的胎面。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-24 14:33:00

同步某物有两种方法。可以使方法同步:

代码语言:javascript
复制
public synchronized void doSomething() { 
    // safe to do stuff
}

也可以对对象进行同步:

代码语言:javascript
复制
synchronize( object ) {
    // safe to do stuff
}

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

令人困惑的是,当您将同步关键字添加到方法中时,它实际上只是锁定了“this”引用。

代码语言:javascript
复制
public synchronized void method() { }

与以下相同:

代码语言:javascript
复制
public void method() {
    synchronized( this ) {
         // this may help clarify
    }
}

这就是你所得到的。当对象被同步时,其他线程中的任何其他对象都无法访问它们。这件事很难搞清楚。我推荐以下书:

Java并发在实践中由Brian等人。链接:http://amzn.com/0321349601

票数 1
EN

Stack Overflow用户

发布于 2014-12-24 14:52:38

帮助我理解我的对象的哪些代码块只能用于名为Method1.的方法。

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

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

票数 0
EN

Stack Overflow用户

发布于 2014-12-26 12:53:49

你得知道

代码语言:javascript
复制
void synchronized myfunc() 

是指:

代码语言:javascript
复制
void myfunc() {
  synchronized (this) {
  }
}

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

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

代码语言:javascript
复制
final MyClass a = new MyClass();

// Thread 1:
a.myfunc();

// Thread 2:
a.myfunc();

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

但是,在以下设置中:

代码语言:javascript
复制
final MyClass a = new MyClass();
final MyClass b = new MyClass();

// Thread 1:
a.myfunc();

// Thread 2:
b.myfunc();

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

如果要以下列方式编写代码:

代码语言:javascript
复制
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)的一个简短的表达式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27638310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档