如何使用Lock指定要在java中锁定的对象

时间:2014-09-25 04:44:21

标签: java multithreading concurrency

使用synchronized(内部锁定)关键字进行锁定,我们可以执行以下操作:

public void addSum(int a) {
   synchronized(q) {
     q.add(a); // q is say a Queue
   }
}

在上面的代码中说当一个对象试图调用addSum()方法,即x.addSum(10)时,锁将保持在'q'而不是x。因此,使用同步我们可以锁定一个不是实际调用对象(Class)的对象。

下面我使用了来自java并发包的Lock,有没有办法指定锁定应该在哪个对象上(就像在上面的代码片段中使用synchronized一样,指定锁定/同步应该在'q上“)。但是当我使用Lock时,我没有指定锁应该在哪个对象上。可以吗?

public void addSum(int a) {
   lock.tryLock();
   q.add(a);
   lock.unlock();
 }

我确实参考了 - http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html。然而,正在寻找更小的例子来清除我的概念。

2 个答案:

答案 0 :(得分:1)

不,Lock个对象与synchronized的工作方式不同。 synchronized无法在方法调用中启动并在方法调用之外到达。您展示的模式

lock.tryLock();
q.add(a);
lock.unlock();
只有在相反的情况下才有可能

Lock个对象通常通过原子方式打开/关闭开关/标志来工作,表明它们已获取或释放锁定。

答案 1 :(得分:1)

我认为你误解了“锁定”这个词的含义。假设调用此方法:

void foobar() {
    synchronized(x) {
        y.doSomething();
    }
}

当线程在x调用中时,我们说y.doSomething()被“锁定”,但阻止其他线程访问字段或更新{的字段{1}}。 x关键字意味着一件事,只有一件事。

JVM不允许两个线程同时在同一个对象上同步。

这意味着所有。你如何使用它取决于你。我的示例是使用它来防止synchronized同时在多个线程中被调用,但只有在对y.doSomething()的每次调用都以相同方式受到保护时它才有效,并且只有在y.doSomething()始终引用同一个对象。

java.util.concurrent.ReentrantLock类的工作方式大致相同。 JVM唯一的保证是没有两个线程可以同时“锁定”同一个ReentrantLock对象。就是这样。其余的由你决定。


P.S。,您的第二个示例不测试x返回的值。那是个错误。如果lock.tryLock()返回false,则表示无法锁定锁。