srock
srock

Reputation: 413

How to specify an object to be locked in java using Lock

Using the synchronized(intrinsic locking) keyword for locking, we could do something like:

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

In the above code say when an object tries to call the addSum() method i.e. x.addSum(10), the lock will be held on 'q' and not x. So using synchronization we could lock an object which is other than the actual calling object(Class).

Below I'm using Lock from java concurrent package, is there a way to specify which object should the lock be on (i.e like in the above code snippet using synchronized it was specified that the lock/synchronization should be on 'q'). However below when I'm using Lock, I haven't specified on which object should the lock be on. Can it be done?

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

I did refer - http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html . However was looking for much smaller example to clear my concept.

Upvotes: 0

Views: 165

Answers (2)

Solomon Slow
Solomon Slow

Reputation: 27190

I think you misunderstand what the word "lock" means. Suppose this method is called:

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

We say that x is "locked" while the thread is in the y.doSomething() call, but that does not prevent other threads from accessing fields or updating fields of x. The synchronized keyword means one thing, and one thing only.

The JVM will not allow two threads to synchronize on the same object at the same time.

That's all it means. How you use it is up to you. My example is using it to prevent y.doSomething() from being called in more than one thread at the same time, but it only works if every call to y.doSomething() is protected in the same way, and it only works if x always refers to the same object.

The java.util.concurrent.ReentrantLock class works much the same way. The only guarantee that the JVM makes is that no two threads can "lock" the same ReentrantLock object at the same time. That's all it does. The rest is up to you.


P.S., Your second example does not test the value returned by lock.tryLock(). That's a mistake. If lock.tryLock() returns false, that means it failed to lock the lock.

Upvotes: 1

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280142

No, Lock objects don't work the same way as synchronized. synchronized cannot start within a method invocation and reach outside that method invocation. The pattern you've shown

lock.tryLock();
q.add(a);
lock.unlock();

would only be possible if the opposite were true. Lock objects typically work by flipping on/off a switch/flag atomically, indicating they've acquired or released the lock.

Upvotes: 1

Related Questions