aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes synchronized and ReentrantLock Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "synchronized and ReentrantLock" Watch "synchronized and ReentrantLock" New topic
Author

synchronized and ReentrantLock

Ziji (Jay) Zhang
Ranch Hand

Joined: Dec 17, 2004
Posts: 42
Hi,
I have been searching for topics regarding the usage of synchronized and reentrantLock but had no luck.
In my project, I followed the Andrew's book, using ReentrantLock, as it
is more object oriented, and you can also upgrade to hand-over-hand locking.
But I still have a question that I cannot answer:
For example, for this method using ReentrantLock:


where lock is an instance of ReentrantLock decared as member of lockManager class.

Is it equivalent to:



or to :

CODE]
public boolean isLocked(int recNo) throws RecordNotFoundException {
synchronized (this){
return lockedRecord.containsKey(recNo) ;
}
}
[/CODE]

???
Can any one shed some light on this?

Ziji


SCJP(94%)
Gabriel Vargas
Ranch Hand

Joined: May 16, 2007
Posts: 145
Hi Ziji, i first begin with this paragraphs from Javadoc of Lock class:


Lock implementations provide additional functionality over the use of synchronized methods and statements by providing a non-blocking attempt to acquire a lock (tryLock()), an attempt to acquire the lock that can be interrupted (lockInterruptibly(), and an attempt to acquire the lock that can timeout (tryLock(long, TimeUnit)).

A Lock class can also provide behavior and semantics that is quite different from that of the implicit monitor lock, such as guaranteed ordering, non-reentrant usage, or deadlock detection. If an implementation provides such specialized semantics then the implementation must document those semantics.

Note that Lock instances are just normal objects and can themselves be used as the target in a synchronized statement. Acquiring the monitor lock of a Lock instance has no specified relationship with invoking any of the lock() methods of that instance. It is recommended that to avoid confusion you never use Lock instances in this way, except within their own implementation.


Whe you defines



It is rigth, the main purpose of Lock class is provides same and more functionality than you can obtain with a synchronized block (see Javadoc Lock class), don't forget it seems more object oriented but for simple things is preferred use a synchronized block. In this code you don't think in a monitor, you think in a lock object than manages all operations.



Compiles but it is a bad programming practice because you use a Lock object as a monitor and javadoc of Lock class prevents it because generates confusion.



Is the classic synchronized block usage. From my prespective first and third are equivalent, not equal because in first you have a Lock object and in third you have a monitor (this) and second are definitively a wrong choice. If you want for example chaining locks or have an object than manages a reentrant lock (as i do in my assigment, creating this object in the lock manager an usign it in data class) you can use Lock class, but if you no have a good reason you can use perfectly a synchronized block.

I hope it help you.


Gabriel Vargas
SCJP, SCJD, now studying for SCWCD and working to be a better person
Ziji (Jay) Zhang
Ranch Hand

Joined: Dec 17, 2004
Posts: 42
Gabriel,
Thanks for your explanation.
It is more clear to me now.
I am used to use intrisic lock mechanism.


ziji
David Nemeskey
Ranch Hand

Joined: Nov 08, 2006
Posts: 52


Compiles but it is a bad programming practice because you use a Lock object as a monitor and javadoc of Lock class prevents it because generates confusion.


Actually, no; he uses a simple Object, just calls it "lock" It is not a bad programming practice because of that; it is bad because it simply does not work. The Object on which the code synchronizes is created in the method itself. So two parallel calls to the method "synchronize" on two different objects, meaning there will be no synchronization at all. I guess you meant



, which is exactly the same as synchronized (this).

Anyway, I have a requirement, that states threads should not consume CPU while they are idle, and that can only be satisfied by one lock for each record. So I use a synchronized block to access the lock map, and then with hand-in-hand locking, lock the ReentrantLock object in the map. In other words, I did not really choose between the two
Gabriel Vargas
Ranch Hand

Joined: May 16, 2007
Posts: 145
Hi David,

You are right, this piece of code doesn't work, i try to put the following piece of code than really is a bad practice:



Sorry about that.
Ziji (Jay) Zhang
Ranch Hand

Joined: Dec 17, 2004
Posts: 42
Thanks for the comments.




I read the Java tutorial,

It says that syncronized on this and synchronized on a member lock of this
are not equivalent. See the link:

http://java.sun.com/docs/books/tutorial/essential/concurrency/locksync.html

Ziji
Ziji (Jay) Zhang
Ranch Hand

Joined: Dec 17, 2004
Posts: 42
I guess the difference is that
if you use synchronized(this), you lock every thing in this object.

But if you use:
synchronized(lock){}, you can also specify what you want to be synchronized, only a member of this object, or the whole object.

So you can achieve synchronized(this) with synchronized(lock), but it is not true the other way around,


In this case, all other member variables can still be accessed in non-synchronized method/block.


Ziji
Ziji (Jay) Zhang
Ranch Hand

Joined: Dec 17, 2004
Posts: 42
I guess the difference is that
if you use synchronized(this), you lock every thing in this object.

But if you use:
synchronized(lock){}, you can also specify what you want to be synchronized, only a member of this object, or the whole object.

So you can achieve synchronized(this) with synchronized(lock), but it is not true the other way around,


In this case, all other member variables can still be accessed in non-synchronized method/block.


Ziji
Gabriel Vargas
Ranch Hand

Joined: May 16, 2007
Posts: 145
Hi Ziji,


I guess the difference is that
if you use synchronized(this), you lock every thing in this object.


I remember when i read Andrew's book there is an explanation about that, when you lock an object doesn't lock his members, there would be because mapping all members could be expensive in terms of proccesor and memory and can cause deadlock easily.


So you can achieve synchronized(this) with synchronized(lock), but it is not true the other way around


When you lock with this or with an object called lock, the only diference is the object locked (called monitor), you can use another object you want to act as monitor and you can have more than one monitor, the really important is when you synchronize you keep in mind what is the monitor you use to syncrhonize diferent pieces of code.

I hope it helps you.
Valentin Jacquemin
Ranch Hand

Joined: Feb 15, 2006
Posts: 35
I think that the Object lock is better for one reason. If someone use your api with the synchronize(this) solution it's possible to do a deny of service in that way:



In that way, the LockManager will not be able to be used. So with a private lock in the LockManager a deny of service attack will not be possible.

I hope that I'am clear with my english
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: synchronized and ReentrantLock