Hi, Introduction ------------ There has been some discussion recently about why some people received a mark of approximately 44/80 for the "locking" score on the exam. This article attempts to make an educated guess as to why. It turns out that many of these people were simply happy to pass; but, in my opinion, if you get marked down significantly in an area, why wouldn't the examiner tell you why? To me, it makes little sense not to tell someone, even if the explanation is in general terms; and, to attempt to determine why is a legitimate area of inquiry so that 1. Future testers are made aware of what is and what is not important to learn and exercise on the exam, 2. Past testers, if they wish to, can re-submit their exam. It is my guess, that the "locking" part of the exam covers two things: 1. How you handle multi-threading, 2. The actual LockManager class itself, 3. and, perhaps other things, but the above two being primary. For RMI-based solutions, writing the "server" simply means to expose your remote implemenations to the client: done: probably you have just bagged 40 points or however much this "server" section is worth. [Of course, there may be subtleties involved, so I'm not saying it is completely trivial.] But, once those threads start using that remote object, an object which is part of a server-side system whose goal is to interact with a file system in a thread-safe manner, creating thread-safe code and creating a correct LockManager are the factors weighed into the 80 points for this section called, somewhat misleadingly, "locking." I say somewhat misleadingly, as it is not immediately obvious; but, when you think about it, almost all the RMI-based server-side code focuses on the distribution of shared resources, which in short is, locking. I speculate that if a multi-threaded LockManager was written correctly, but all other parts of the server-side system were not thread-safe due to very easy oversites which can occur (i.e., multi-threaded programming is difficult, and particularly so for the uninitiated), that this can quite easily lead to a 40 point deduction; and, it may only take "one multi-threaded oversite" to get the 40 point deduction. There are two primary, yet distinct, RMI approaches that can be used: The Multi-Threaded One Group: The server-side code offers one instance, called, perhaps, DataImpl or MyServerImpl to the N clients. This is where the danger lurks. Because N clients share one instance of that server-side object, and that server side object, called DataImpl or MyServerImpl, is multi-threaded, and must be written in a thread-safe manner (and, of course, the LockManager also is multi- threaded). The Single-Threaded N Group: The server-side code uses a factory to offer up one, unique DataImpl or MyServerImpl to each of the N Clients. Here, each instance of DataImpl or MyServerImpl is single-threaded because each instance is only used by one client, and this is much easier to code. Of course, the LockManager is multi- threaded. I speculate that the Single-Threaded N Group rarely loses 40 points in the "locking" section. I speculate that the Multi-Threaded One Group more often loses 40 points in the "locking" section. Ammendment: while the Multi-Threaded One Group will experience more complications, I think the loss of 40 points may be in how shared resources are used, such as how the LockManager is used. Now, of course, if an individual lost many points because the LockManager was not coded correctly, then that particular issue is not being addressed here. Resources --------- Mutli-threading is a complex topic. I find it interesting, even though I am far from expert in it. It is very easy for people preparing for the exam to brush up on the topic; and, it is very easy for people who have lost 40 or so points on "locking" to look at their code and attempt to find their own errors, if any exist. It may not be so easy to actually find the errors, but if those in the Multi- Threaded One Group start snooping around a little, they may start to find errors. One way to increase the probability of finding these errors in multi-threaded coding, though not a guarantee, is to be pointed to the right resources. Another quite equally valid option is to join the "Single-Threaded N Group," where anyone will have fewer headaches writing logically correct code. An excellent introduction to this topic can be found for free at Bruce Eckel's web site: it is the chapter called Concurrency in the 3rd edition of his book entitled Thinking in Java. You can download the .html version of this book using the following link: http://22.214.171.124/ Hints ----- I hope to post an article about multi-threading soon, but before then, here are some hints (please keep in mind that I am far from an expert): The following may potentially be very dangerous:
and in a multi-threaded environment, could be coded like this:
the point being this: in a multi-threaded environment, the test to see if the record is unlocked must be synchronized for all methods doing this, otherwise, ThreadA determines the record is unlocked, but before ThreadA can lock it down, ThreadB has locked it down. Ammendment ---------- the point being this: in a multi-threaded environment or a single-threaded environment, the test to see if the record is unlocked must be synchronized for all methods doing this, otherwise, ThreadA determines the record is unlocked, but before ThreadA can lock it down, ThreadB has locked it down. In other words, my theory should not focus on whether DataImpl is single-threaded or multi-threaded, though a multi-threaded DataImpl will contain more pitfalls, but on how the shared resource, LockManager, is used. End Ammendment
So, these are my speculations. With sufficient resources, such as Bruce Eckel's chapter on concurrency, anyone who lost 40 points has a chance to find the logical error in their code, even though their code performed well during their own personal testing, for keep in mind, that testing cannot prove that the code is thread-safe; if a potential error exists, you could potentially have been or will be marked down. Thanks, Javini Javono [ February 14, 2004: Message edited by: Javini Javono ]
Wouldnt the LockManager class itself be the more logical place to put the synchronisation?
SCJP (1.4), SCJD (1.4), SCWCD (1.3), SCBCD (1.3)
Joined: Dec 03, 2003
Hi, Certainly the LockManager is multithreaded, and so synchronization is important; but, I would not consider it extremely tricky or containing many pitfalls, though people's opinions may vary considerably. So, I am suggesting that if you are in the Multi-Threaded One Group, then your DataImpl or ServerImpl which uses the LockManager, needs to be thread safe; and, given that writing thread safe code is tricky, the chance for error can, for some, including me, be quite great, and that failure in this part could result in a 40 point loss. Ammendment: I'm suggesting to look beyond the LockManager class; whether or not anyone is in one of the above two groups, how the shared resource, the LockManager is used, is just as important as the LockManager itself. Thanks, Javini Javono [ February 14, 2004: Message edited by: Javini Javono ]