我对并发性相对较新。我在Oracle网站上练习并发。我被困在以下例子中: -
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
我想知道这种类型的锁如何比使用synchronized(this)类型锁更有用?在哪种情况下应该首选这种锁?
由于
答案 0 :(得分:4)
当您拥有一个需要比对象本身更精细的排除分辨率的单个对象时,它非常有用。换句话说,具有多个资源的对象需要受到保护,但不一定是彼此保护。
在pthreads世界中被买入,这很容易理解,因为互斥锁及其受保护的资源往往总是分离 - 在Java中找不到使用对象的方便的简写锁。
例如,假设每个对象都有一千个整数的数组,并且您希望一次锁定一组一百个(0xx,1xx等)以获得最大的并发性。
在这种情况下,您创建了十个对象,每组一百个,并且您可以锁定单个部分的数组。这样,如果你有一个线程摆弄0xx
和4xx
块,它将不会阻止另一个线程进入并使用7xx
块执行某些操作。
现在这是一个非常人为的例子,但这个概念偶尔会出现在现实中。
在您给出的具体示例中,一次只能有一个线程进入并同时增加c1
,但lock1
上的锁定仍然允许另一个线程进入并更改{{ 1}}。
使用对象(c2
)锁定,可以减少并发性,因为this
和c1
无法同时更新,尽管没有冲突。
答案 1 :(得分:1)
对象锁定只是一个对象显式锁定临界区。 synchronized(this)描述了您通过当前对象锁定临界区。
答案 2 :(得分:1)
对于inc1
和inc2
有两个单独的锁,在你想要确保没有两个并发线程可以同时调用同一个方法,但你在哪里 do 希望允许两个并发线程在同一个对象上调用不同的方法。
在您的示例中,如果线程1调用inc1
,则阻止线程2调用inc1
,直到线程1完成。但是,第2个帖子可以免费拨打inc2
。