2011-08-01 57 views
2

我需要澄清关于javaron中同步关键字的工作原理。Java同步关键字 - 它是否保护类方法不被同时执行?

使用下面的示例类。现在

class Carrier { 

    private String[] _collection = new String[2]; 

    public Carrier() { 
     this._collection[0] = "abc"; 
     this._collection[1] = "123"; 
    } 

    public syncronized void change(int cId) { 
     Thread.sleep(3000); 
     this._collection[cId] = "changed"; 
    } 

} 

,在应用中的一些地方,它引用了运营商级的同一个对象实例中,.change()方法被调用时,有可能在同一时间。

...carrier.change(1); 

...

...carrier.change(1); 

请问syncronized关键字防止方法的asyncronized执行?它是否将呼叫排队到.change(),等待每个人完成?

+0

'它会简单地排队呼叫。变化()'。取决于你排队的意思。执行顺序没有指定,所以它不是一个有序队列,但是,其他线程将被迫等待。 – Kaj

回答

2

是的,它会阻止两个方法调用同时执行。

这确实是​​关键字的主要用途。

当一个同步方法运行时,它会在它所调用的对象上获得'锁定'。这意味着当该方法持有该锁时,不能在该对象上运行其他同步代码。一旦方法完成执行,它将释放该锁,并且其他同步方法可以获取该对象上的锁。

1

是的,是的。 (请注意它是​​,而不是syncronized

4

是的,第二个线程会在第一个线程执行时阻塞。这是因为他们都试图通过this获取相同对象上的显示器,在这种情况下。所以,你的change方法等效于:

public void change(int cId) { 
    synchronized (this) { 
     Thread.sleep(3000); 
     this._collection[cId] = "changed"; 
    } 
} 

我个人不喜欢上同步“这个”,因为这意味着任何其他代码访问对象本身能获得相同的显示器。我希望创建一个对象只是为锁定其只有类内代码可以访问:

private final Object lock = new Object(); 

public void change(int cId) { 
    synchronized (lock) { 
     Thread.sleep(3000); 
     this._collection[cId] = "changed"; 
    } 
} 

这将仍然有两个线程调用同一个对象上change方面同样的效果,因为两个线程仍然会获取相同的显示器 - 只是与特定于锁的对象关联的显示器。

+0

单独锁定对象上的优点。 – dropson

1

是 - synchronized关键字阻止不同线程同时执行该方法。

注意:“类方法”是一种static方法。你的问题中有一个“实例方法”(即非静态)。

+0

太好了。我会将其添加到我的词汇表中。与“正在”(不是beeing);-)一起 – dropson

1

​​用于防止同时访问cuncurrent编程。 例如,当您需要客户端,一个读取,另一个写入:

锁定here的详细解释。