这个锁怎么用呢?

时间:2014-11-25 06:17:01

标签: java concurrency

我对并发性相对较新。我在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)类型锁更有用?在哪种情况下应该首选这种锁?

由于

3 个答案:

答案 0 :(得分:4)

当您拥有一个需要比对象本身更精细的排除分辨率的单个对象时,它非常有用。换句话说,具有多个资源的对象需要受到保护,但不一定是彼此保护。

在pthreads世界中被买入,这很容易理解,因为互斥锁及其受保护的资源往往总是分离 - 在Java中找不到使用对象的方便的简写锁。

例如,假设每个对象都有一千个整数的数组,并且您希望一次锁定一组一百个(0xx,1xx等)以获得最大的并发性。

在这种情况下,您创建了十个对象,每组一百个,并且您可以锁定单个部分的数组。这样,如果你有一个线程摆弄0xx4xx块,它将不会阻止另一个线程进入并使用7xx块执行某些操作。

现在这是一个非常人为的例子,但这个概念偶尔会出现在现实中。

在您给出的具体示例中,一次只能有一个线程进入并同时增加c1,但lock1上的锁定仍然允许另一个线程进入并更改{{ 1}}。

使用对象(c2)锁定,可以减少并发性,因为thisc1无法同时更新,尽管没有冲突。

答案 1 :(得分:1)

对象锁定只是一个对象显式锁定临界区。 synchronized(this)描述了您通过当前对象锁定临界区。

答案 2 :(得分:1)

对于inc1inc2有两个单独的锁,在你想要确保没有两个并发线程可以同时调用同一个方法,但你在哪里 do 希望允许两个并发线程在同一个对象上调用不同的方法。

在您的示例中,如果线程1调用inc1,则阻止线程2调用inc1,直到线程1完成。但是,第2个帖子可以免费拨打inc2