Link to home
Start Free TrialLog in
Avatar of 2djohn
2djohnFlag for United States of America

asked on

JAVA RMI SERVER FILE SHARING and Locking

I am using RMI in a multiuser situation... many users may at the same time want to access my "database" (just a file of user id's).  How do I go about locking my RandomAccessFile so that one applet will sleep while another is writing to it???  Even if I open it is as "rw" mode, other applets do not throw exceptions when they open it in "rw" mode...  A quick answer would be great!!!
ASKER CERTIFIED SOLUTION
Avatar of heyhey_
heyhey_

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gadio
gadio

What you need to do is to implement multy threaded data locking pattern such as "readers writers". I think I have a piece of code that does that. If you want, give me your email I'll send it over. Basiclly, the pattern sets the policy so that any number or readers can approach the data. When a writer comes in, its blocked untill all the readers stop reading. Additional readers are blocked until the writer(s) finish its task. This is a basic algorithem, and it can be extended for a more advanced algorithem of blocking nodes in a tree data strucure, etc.

[heyhey] I think that the solution you offerd is less efficient. You suggest to lock ANY approach to the data. In that case if N users (where N is big) wants to read the same reasource (file in that case) you would get very poor performance. If all N are reading, there is no reason to mutually lock the reasource, and thats what the readers writers pattern is about.
gadio:

yes my solution makes just a general synchronization of the data access.
It does not allow multiple readers at the same time.
but it won't be easy to implement such behaviour because
every reader will use different pointer inside the file (that is different reading offset)
(take a look at the RandomAccessFile.seek() method)

so you will need to implement some basic (atomar) actions
(something like
 push curPos
 mov curPos, newPos
 read bytes
 pop curPos
)

and synchronize them.

and you can easy synchronize these basic actions using my approach.

heyhey,

I disagree. The access to files will keep on beeing the same (that is, each thread opens up a handle to a file) however, no thread will make a set of operations (set of read or set of writes, or a read and writes) before he gets the premition of the readers writers manager. Its a sort of a token thing. When it finishes its operations it will give back the token. Some databases uses these techniques.
my technique is the best technique when you don't have additional object managment -
- you have exactly ONE server object - that works with the database / file.
- you have many clients objects that send requests to the server object.
- server can't distinguish between different clients objects.

so in this case server object receives requests as a simple method calls (through RMI).
the only possible technique in that situation is isolating the critical sections.

if you can manage client connections yourself (for example starting another thread for each client / client request)
you can implement a much better technique (many reader / one writer design pattern).

It all depends on the real design problem ...

regards
  heyhey
No, you dont have to manage client connections yourself. All you need is to count the number of clients that got a reading token and didn't gave it back. I'm surprised that you didn't heard about this pattern - its quite known.  :-)
- you probably have to manage client requests if you want every client request to use different handle to the File ...
- after maniging the client requests, you will end up with implementing yourself a queue which manages Request with Priorities. and you'll have to manage yourself all the low-level Thread (request comes from different Threads) stuff.
as far as I remeber it's not easy to make some 'manager' Thread to wake up other 'simple' Threads that are 'waiting' (not sleeping) at the queue.

and, yes, "Many readers / one writer" is a well design pattern. (I think a mentioned this). But "only one in a critical section" is a much more popular design pattern, much easier to implement and almost a standard for Java.

as I said it all depends on the Current Problem. Every problem has its own Answer. and there isn't a Universal Answer to All Problems :))

of course if 2djohn needs much more finer control locking control - you win :) - you was the first one that mentions the "reader/writer paradigm"

best regards and Good Night :)
  heyhey
Yep. Good night & Cya... :-)
P.S - the implementation of this pattern (rds,wrtrs) with blocking interface is not a big deal. Its a one page class + an interface of two functions.

Regards, gadio

Please send me an example to joe@macropoint.com (if you don't have something in mind). I'm curious to see implementation of this design pattern ( I mean N readers / 1 writer).

Best regards, joe.
Avatar of 2djohn

ASKER

Hi guys-

Sorry I have not handed out the points yet- I was just very busy.  I have doubled the points in appreciation and will send em along after this comment (even if no response).  I see what you guys are saying, I guess my main thing that I don't understand is how this works within the RMI server context!  If the remote object that I create is implementing these syncronized threads- then does that mean that every applet around the world DOES share this code on the server?  I.e. the applet on one client cant get at the the same critical code if another client's applet is already writing?

I am looking for a solution where everyone can read simulataneously, but once someone gets a "lock" for writing, obviously no one can read or write.

Also, if the applet that is in the synched code "crashes", does java take care of that?

My e-mail is jflanagan@assistware.ie, or 2DJohn@hotmail.com if you prefer.  Any code samples would be great!!!

Thanks everyone,
John
as far as you register ONE RMI Server object, you'll have exactly one server Object running.

all the client (applet) request are handled from RMI and transferred to than one server object.
the question is how many Threads (started from the RMI on the server side) can call simulantesly. I think that this depends highly on the RMI implementations (yes there are more than one implementation :).

I don't quite you 'applet crash' problem

applet calls method on some RMIserverObject.
RMI kernel on the client machine blocks the calling thread, connects with the RMI kernel on the server machine and sends the marshalled request. then waits for reply.
RMI kernel on the server side receives the request, demarshalls the parameters, excutes the appropriate method on the Server object (calling method on a local Object). After reseiving result it marshalls it, sends it back to the client.
RMI kernel on the client side receives the result, demarshalls it unblocks the calling Thread and returns the appropriate result to the calling object.

Everything that is not specified in the RMI specification depends on the (current) implementation.
(I don't have the specification at the moment ...)

I would suggest you first to experiment with full locking (when somebody works with the data, nobody else can work with it). It is much easiser to implment in distributed system. After you have working implementation, you can think of some kind of speeding up the system. (althought  using read/write locking presumes that you have more than one Server Objects that share a common resource ...)

best regards
  heyhey