• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Identifying the thread that placed the lock

 
Douglas Kent
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wanted to get the collective wisdom on the approach I'm using to identify the thread that placed the lock. The directions state that if a thread attempts to unlock a record that it did not lock, then the unlock call should do nothing.
I've got a Vector of :
private class LockStruct {
Thread threadThatHasLock;
} // the initial reference is owned by Data and
// instantiated at Data construction
Then, in the "lock" method, keep a record of which thread placed the lock. I'm using RMI, with a server that starts up 10 servant threads to handle requests. The "lock" method is in the Data object, and is called by the public modify method in Data.
LockStruct lockRec = new LockStruct();
lockRec.threadThatHasLock = Thread.currentThread();
Then, on unlock, the following:
LockStruct Lstr = (LockStruct)lockVec.get(record);
if (Lstr.threadThatHasLock != Thread.currentThread()) {
return;
}
I believe this will work....but any thoughts would be appreciated.
 
vladimir levin
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think you should count on the fact that RMI will use the
same thread to unlock your record as it did to lock it. The
RMI spec does not make any such guarantees, and your code
should therefore not make any such assumption.
Just my 2 cents
Vlad
 
kamal kant
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Douglas Kent:
I'm using RMI, with a server that starts up 10 servant threads to handle requests.


how could you be able to start exactly 10 threads to survice requests. i made my rmi server by extending unicatremoteobject. is there any other way exist to do that. because by extending unicastremoteobject the control for server services is not in our hand . have you written rmi server from scratch. if this is the case then really you have done a great job. can you please give me some hints about your rmi server. my scjd specs told me that i have to implement a multithreaded server. but i am unable to understand that in extending unicastremoteobject how can server get notifid when a client made any request to it by calling any of the data method. i think this way of implementing rmi server is from some higher level thats why i am unable to access all these low level information.

 
Douglas Kent
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kamal,
I am simply starting up 10 servants like so:
/*
* create the 10 instances
*/
DataRMIimpl DataRef1 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef2 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef3 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef4 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef5 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef6 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef7 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef8 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef9 = new DataRMIimpl(args[0]);
DataRMIimpl DataRef10 = new DataRMIimpl(args[0]);
/*
* and bind to the registry
*/
Naming.rebind("Data", DataRef1);
Naming.rebind("Data", DataRef2);
Naming.rebind("Data", DataRef3);
Naming.rebind("Data", DataRef4);
Naming.rebind("Data", DataRef5);
Naming.rebind("Data", DataRef6);
Naming.rebind("Data", DataRef7);
Naming.rebind("Data", DataRef8);
Naming.rebind("Data", DataRef9);
Naming.rebind("Data", DataRef10);
Quite far from re-implementing an RMI server. Perhaps I miss-spoke when I indicated 10 threads. Anyway, the RMI server will assign one of the servants to handle an incoming request. Now, assuming the call to "lock" is on the server side, I don't see how a thread could be re-assigned. I would think it would run to completion...
 
Aron J. Skantz
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Douglas,
I thought the nice thing about RMI and a great deal of the concept with it was that the server handles the thread-issues for you. It creates threads as clients connects and threads live as long as the client makes calls, and then dies after a timeout-period. If the same client makes more class later a new thread is created for him. All this goes on "behing the scene", and we dont have to worry about it.
So, what im trying to say here is that creating 10 different instances of the implementation is to go against the whole thought behind RMI, and judging from your code only the last instance will be bind anyway since you bind them in the same name "Data" and thus overwrite the to "Data" assigned instance on every new bind-line; resulting in that only DataRef10 will be bound.
... or have I missunderstood the whole thing?
Regards,
Aron
[This message has been edited by Aron J. Skantz (edited April 04, 2001).]
 
Adrian Yan
Ranch Hand
Posts: 688
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Douglas, according to your code, you are not starting 10 threads, I think you created 10 servers, then when you do the rebind, the second will replace the first one, the thrid one will replace the second, ...... So the only server that's actually binded is the last one.
------------------
 
Douglas Kent
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, I guess I read the Sun educational materials wrong. My reading of "Distributed Programming with Java Technology" on page 3-25, 26 was that unless you started more than one servant, your incoming requests would be single-threaded. To quote, "They (the servers) must be able to instantiate on demand and discard them after a period of no-usage".
This does not sound like "Leave the driving to RMI"...
So assuming you are right, how DO you create more servants? The external clients know them by one name, in my small sample, this name is "Data". You would have to bind them to different names and publish these names...
 
R Bischof
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You just have to bind one server object to the registry. You don't have to worry about maintaining worker threads, this will be done by the RMI environment for you.
If multiple request come in from the clients, this object is reused with different threads. That's why your code must be thread safe.
If you need to identify one specific client, here is what I did:
The client generates a unique id using the following method
String sessionId=new java.rmi.dgc.VMID().toString();
This uniquely identifies the running VM instance and is passed to the server on every call that requires this identification.
my $0.02
Rainer
 
Douglas Kent
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rainer,
Thanks very much...looks good after reading up on the class. I have implmented lock and unlock as methods of the Data class, and using RMI. When the client calls lock and unlock, will the VMID generated be that of the server VM or the client? Did you
modify the signature of lock and unlock?
 
Douglas Kent
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After testing the scheme using VMID, it turns out that each time you call new VMID(), you do indeed create a new id, one that is not carried across invocations of lock and unlock. So, if lock calls new VMID() and stores it in the lock structure for that record, the same connection, when calling unlock which has a call to create a new VMID will generate another id, different from the one generated by lock.
Perhaps I'm approaching it wrong.
One clue provided by the SCJD directions is the implication that each "connection" could have a unique id that persists. I have searched through the java.rmi classes and have not found a method or field that will server to uniquely identify a particular connection. Haa anyone been able to do this?
Much thanks,
 
Aleksey Matiychenko
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried VMID idea too and found the same thing.
The idea that I came up with is this:
1. I created a RecordLock object that handles all lock/unlock for itself. The methods in RecordLock are synchronized so I do not have to synchronize on Data object itself. The constructor for the class takes in an LockID interface that has one method getClientID.
In my local mode the implementation of the getClientID is by the thread owner (Thread.currentThread.getName())
In my server mode I am going to use Custom client factory to get unique user id
 
Aleksey Matiychenko
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A follow up
I have implemented the SocketFactory idea and it work well in identifying the client. Basically I am going to have my client enter the user name whene login in using network mode and then supply that name to the custom client using System.setProperty call. The socket will read that name and give it back to the server.
 
R Bischof
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kent,
sorry for the late answer, I was on vacation ;-)
What I do is the following:
I have an RMI server called RMIDataServer that encapsulates the Data object used to access the datafile on the server.
On the client side I have an RMIDataAdapter which implements the same interface as Data does. RMIDataAdapter handles all the RMI stuff and behaves like a local Data object, so the client does not know if it is connected to a server or a local data file.
At the time the RMIDataAdapter is creates a VMID using the method mentioned in a previous post and stores it as a static property. This VMID is passed to the server on every request that involves locking. These methods do not only involve lock and unlock but alos add, delete and modify as the server should check if the session has a valid record lock (the complete DB may also be locked, thus preventing any modifcation, even adding a record should not work).
The client uses the same VMID for all requests until the RMIDataAdapter class is garbage collected (which is very unlikely at all given the memory requirements of this assignment).
Reg
arding the modifications of the lock and unlock sigantures:
I provided a new lock siganture
>void lock(int recNum, String sessionID)
which is called by the RMIDataAdapter with the sessionId. The original void
>lock(int recNum)
is still there and is used in local mode. All it does is call the method
>lock(recNum, "DummyID")
to lock a record for dummy ID which is used in local mode.
That's all
Rainer
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic