wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes isLock(int):boolean method and the synchronized block 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 "isLock(int):boolean method and the synchronized block" Watch "isLock(int):boolean method and the synchronized block" New topic
Author

isLock(int):boolean method and the synchronized block

Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hallo,

I think the title for this post must be "Test methods in multithread environment" - it describe better the thema but it seams thet I have a limit size for the title. Ok let's start .

My lock manager has a test method - isLocked(int):boolean, it is used to test if a record is locked ar not(by other clients). My lock mechanism is relative simple - I have a map with records and clients, that meakes the test method simple also - if the Map contains the record then true. The problems starts when the tst method is used and I think that is that this is a general problem by all the test methods in multithreading environment. The test methods may be correct from the syntactical point of view, also are thread save but them USAGE can lead to a race condition.

By example :



In this example the isGood():boolean method is corect (syntactical) and is also thread safe.

but lets image how we USE it :



Lets image that two threads access in the same time :
1.Thread t1 tries the condition(test.isNull()) and find it true
2.Thread t2 waits to test also the condition.
3.The thread t1 is suspended after it goes out from if condition (so it release the lock - other thread can use the test method)
4.Thread t2 tries the condition(use the test method) and find it true.
5.Thread t2 goes and execute the if block (test.set(new Value()))
6.Thread t1 does the same stuff.

Here we have a race condition.


A way to avoid it it to let the test metohd whitout syncronze and to synchronize the whole test block with the same lock like the operating methods (set and get in example) - so in your case I synchronize with the Test instance (note that the methods are synchronized to the instance).

So we have :



Ok and now back to my problem, the URLyBird LockManager test method :

isLock(int):boolean

One of my first ideea is to use the same logic(let the test method without synchronize and to synchonize the test block), but my lock for the operation metods is a static map (the record map) and is not visible. For this I chhose to have an othre immutable object like lock and to make it aviable through some methods. So I'll have :


LockManager lm = new Lockmanager();

final Object mulex = lm.getLock();

synchronize (mulex) {
if(lm.isLocked()) {
// do stuff
}
}

Because the lock is a immutable object its value can not be changed accidently by a slappy user. If the user choose to lock the record in the if block(the //do stuff comment is repaced by lm.lock(...)) - the lock(int) method uses the same mulex - no danger of nesting looks nad deadlock.

The onyl main problem is if a wrong impelemented client locks the the mulex
then evrything remains locked.

My questions are :

1.Is this ok ? I mean to provide access to my mulex (even if is a immutable one) ?

2.In my implemetation the clients are "nice" implemented - but if new clients are implemented, by a malicious evil mind programmer, he can lock the mulex (just use a endless loop in to synchronized block). In the same way can be lock also my Data class because it have a lot of metods synchonized on instance. So, do I care to much ?

3.There are others solution to the "test method usage" problem ?



I hope that was not to long (and boring) and I expect you comments/ critics and suggestions.

ThanX Mihai.

[ October 30, 2005: Message edited by: Mihai Radulescu ]
[ October 30, 2005: Message edited by: Mihai Radulescu ]

SCJP, SCJD, SCWCD, OCPJBCD
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Hello Mihai,

Well, after reading several times your post thats what i have understood:
You want to implement a synchronized transactional behaviour in a method.
You have two posibilities, at least:
Synchonizing method:


Or synchronizing a block:

This last provides much more functionality...

You wrote:

But this have no effect, since each time a method call occurs, your sinchronizing object is different

... let the test method without synchronize and to synchonize the test block ...


This is what you have to do if you want to lock at row level (not entire database)...


... but my lock for the operation metods is a static map (the record map) and is not visible. For this I chhose to have an othre immutable object like lock and to make it aviable through some methods. So I'll have :


Then i lost in too much asumptions ...
static map? not visible? immutable object?
Share your design tips and post some pseudocode about that last...

1.Is this ok ? I mean to provide access to my mulex (even if is a immutable one) ?

Ensure that the threads are dealing with the same instances of mulex. Ie, mulex must not be a method scope variable.
Maybe you will be interested in something like:



... a malicious evil mind programmer.... So, do I care to much ?

Of course, Mihai, a malicious evil mind programmer can crack win xp, i think URLyBird wont be out of risk!
But i think would be more interesting caring about a absent-minded junior programmer.

Hope that helped you,
regards Ori


SCJP, OCMJD, OCMJEA
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hi Oricio,

What part from my old post creates problems ?




the LOCK constant (because is static and final) is used to lock all the record manipulating methods(lock(int), relase(int), ...). See the code :


or



The LOCK constant is not visible outside of its class so if I need to acces it I need a get method. I choose the get metohd instead of direct access(remember the LOCK is static) because of flexibility. There are at least two ways to implement a lock manager :
the same lock for all and
each client with his own lock (multiple locks),
if for the first case (the same lock for all) the direct access will be ok in the second case I can get problems.

Thats why I have on my LockManager interface :


What you think ?


But i think would be more interesting caring about a absent-minded junior programmer.


Ok, I take back the "a malicious evil mind programmer" but I still belive that the "absent-minded junior programmer" can make a fatal mistake just by tring (let's say copy/paste from some examples).


Regards,

Mihai.
[ November 02, 2005: Message edited by: Mihai Radulescu ]
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

I think I am sot a singular case, this must be a general problem. I think everybody have to implement a isLock() method.

So Heelp, I need some tips !
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Hello Mihai,
that's what i understand:


That is, your LockManager wraps a collection of static locks and provides access to them.
I supose that locks are static in order to have several instances of LockManager, isn't?
I choose singleton (pooling) pattern for my LockManager, have you thought about it?
From an OOP point of view, and with all my respect, i don't like your LockManager design:
What must a LockManager object offer to his clients?... locking capabilities not? Is getLock() a locking capability? I don't think so. Think about that. As a developer, where would you search the locking implementations, in the data access class? or in the LockManager class?

Ok maybe i am suposing too much and you have solid arguments to do that.
So you share your static instances between all your lockmanger objects. Well, have you thought about concurrency in that design? Is your LockManger class thread safe? (you have an static collection)

I would recommend you having in mind:
- singleton pattern (for your lockManager class)
- bussiness delegate pattern (for your data class related locking issues)

Maybe you find it useful.

Regards, Ori
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hi Oricio,


You are right !
I was blind(you can also read it stupid), I was to close to the solution to see it.
My Data class is singleton and it compose the LockManager and the DataAccess
Because the LockManager is a singleton also I can synchronize the lock and release method on instance and I can use the same instance(I mean the LockManager instance) to synchronize the test blocks.

That means the code before :


code now :



Extra I force the LockManager to be a singeton - private constructor and factory method.


What you think now ?

ThanX once more,

Mihai
[ November 02, 2005: Message edited by: Mihai Radulescu ]
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hi, is me again.

I just play a litle with the new concept the lock manager like singleton, is not bad.But I have the same problem :
My DBMain interface has a metohd :


So I have the same problem, the usage in a if block leads me to a race condition.
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Hello again Mihai,

could you show us the entire interface (provided by Sun)?

Mine nothing says about isLocked()

Regards
[ November 03, 2005: Message edited by: Oricio Ocle ]
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Here is one part - at least lock related part :

[code]
// Locks a record so that it can only be updated or deleted by this client.
// If the specified record is already locked, the current thread gives up
// the CPU and consumes no CPU cycles until the record is unlocked.
public void lock(int recNo) throws RecordNotFoundException;
// Releases the lock on a record.
public void unlock(int recNo) throws RecordNotFoundException;
// Determines if a record is currenly locked. Returns true if the
// record is locked, false otherwise.
public boolean isLocked(int recNo)
throws RecordNotFoundException;
[code]

The rest I think is the same for all (read, update, search amd delete) users.


I think you can understand now my problem.


Regards,
Mihai
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Ok ok
now things become clear...
your specs are very different from mine...

My position would be implement a 3 tier design because there are no cookies.
And implement the transactional behaviour at bussiness level.
Search the forum for "tier" and you'll find lots of information.

Regards, Ori
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

That is a classic:

Should lock methods be callable by the client

Here you'll find useful information

Regards
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hi,
I know, I alreay read this post,
Do you suggest to expose the lock relese and unlock at the cleint side ?


Regards M

[ November 04, 2005: Message edited by: Mihai Radulescu ]
[ November 04, 2005: Message edited by: Mihai Radulescu ]
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Hello again Mihai,
I would expose only business methods like book() or search()

Another posibility would be implement a connection factory in order to identify the clients.

Regards, Ori
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hi, Ori

I know also this post, I'am based my design on this(connection factory) on this.
The design is relative simple
The Data is a sigleton. It also compose the
LockManager and the DataAccess (strategy pattern), the LockManager garants the concutrent access to record and the DataAccess knows how to handle(I/O) the records.
Each client has its own LockAdaptor(connection factory) where are encapsulated used dependent information BUT all LockAdaptors are using the SAME LockManager.

What you think ? Comments ? Critics ?

I think I gona post my desing more in detail in a separate thread.

Regards Mihai.
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Hi Mihai,

It would be better if you'll show some code


The Data is a sigleton


I also have been thinking in implement a connection factory with a singleton data in order to reduce the weight of the "connection objects" but at the time being i have some concurrency problems unsolved...

What kind of objects does your factory return?

I am not sure that what you are saying ...

And how are they passed to the lockManager?
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hallo,

I am back.

So I have a connection factory, this factory builds a data proxy for each client. The DataProxy warps the Data and the LockManager, it contains also the user related infromation - all the Dataproxy ("connection objects" in your last post) are using the same Data instance and the same LockManager.
Because the Data is a singleton I sinchronized all the data manage/manipulate methods.

I hope this will help.

Hey, after this I just have a new ideea.

So I have a DataAccess and a LockManager. Both are instatialized by a singleton class BUT this class IS NOT my Data class - it only holds the DataAccess and the LockManager mechanism and provide access to them. The access is done via proxy (warper) objects and this proxy object implements the DBMain interface (they are the Data objects). Each client will have its own proxy(user dependent information), all the proxy will warps all them actions to the same Data and LockManager.

I like the ideea.

What you think ?

Apropos what design you use ?

Regards,
Mihai
[ November 08, 2005: Message edited by: Mihai Radulescu ]
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Hello again
Ok tell me if i'm wrong:

Case 1:
Your connection object implements a remote interface with locking methods:

And your Data singleton implements the Sun provided interface.
So :


Case 2:
Your connection object exposes business methods like:

It's easy to see that case 1 is thread unsafe, since isLocked() only has sense in a transactional synchronized context like case 2.
So in your case, my date server would expose only business methods.
In that situation, do you think it's necessary having a connection Factory?
why do you need to identify a client?, in order to avoid deadlocks?.
I'm supossing too much... what do you think?
Regards, Ori

[ November 10, 2005: Message edited by: Oricio Ocle ]
[ November 10, 2005: Message edited by: Oricio Ocle ]
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

And how are you passing your client id to the single LockManager instance?
IMO this is potential problem with a connection Factory and a single Data instance...
Regards
[ November 10, 2005: Message edited by: Oricio Ocle ]
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hi Oricio

I think we shoud start a new thread with a better title(something like "Design problems"). I'll think about it and I'll post you back the new title.


Regards,
Mihai.
Oricio Ocle
Ranch Hand

Joined: Nov 30, 2004
Posts: 284

Hello Mihai,
I think it's a good idea.
This begin to seem a private thread
Regards
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

see http://www.coderanch.com/t/187655/java-developer-SCJD/certification/Please-comment-design

Regards, M.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: isLock(int):boolean method and the synchronized block