Meaningless Drivel is fun!*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes How can a deadlock occur in a thin client? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "How can a deadlock occur in a thin client?" Watch "How can a deadlock occur in a thin client?" New topic
Author

How can a deadlock occur in a thin client?

Oliver Rensen
Ranch Hand

Joined: Jul 23, 2004
Posts: 109

Hi everyone,

I have read many threads about deadlock prevention, but I don't understand, how a deadlock can occur. My thin client only calls the book- or the search-method, therefore all the locking code lies on the server:



When a client crashes after locking a record, no deadlock occurs, because unlocking is part of the server. When an exception was thrown during a database-operation, the locked record will be unlocked in any case, because unlock is part of the finally-block, and the unlock-method will call notifyAll() to wake up ALL wait()ing threads.

What's about the following scenario:

  • 1. Client A locks record 1.
  • 2. Client B locks record 2.
  • 3. Client A try to lock record 2 and wait().
  • 4. Client B try to lock record 1 and wait().


  • I can not imagine that this could lead to a deadlock. What will happen in this case? There are 4 threads running on the server. Threads 1 and 2 are currently working on the database. Threads 3 and 4 are wait()ing. When thread 1 (Client A) has finished, it call unlock and notifyAll(). All wait()ing threads are wake up. Thread 3 will check the locked records and wait() again, because record 2 is still locked. Thread 4 will get the lock of record 1 and continue to run. When thread 2 (Client B) has finished, it call unlock and notifyAll(). The only wait()ing thread is thread 3. He will wake up und get the lock of record 2. No deadlock occur.

    I'm not sure whether my assumptions are correct.

    Could someone please comment on my code?

    Regards

    Oliver
    Anton Golovin
    Ranch Hand

    Joined: Jul 02, 2004
    Posts: 476
    A deadlock occurs when a lock is held by a thread which is needed by another thread to proceed, while the first thread needs the lock held by the second thread to proceed.


    Anton Golovin (anton.golovin@gmail.com) SCJP, SCJD, SCBCD, SCWCD, OCEJWSD, SCEA/OCMJEA [JEE certs from Sun/Oracle]
    Robert Konigsberg
    Ranch Hand

    Joined: Jun 23, 2004
    Posts: 172
    Here's how deadlock was able to occur in my client application, and what I did about it:

    In my application for the B&S problem, I have a reservation system. When the operator clicks "reserve", I lock the record. Then a dialog box appears on the client, asking for the client id that identifies the person making the reservation. (This client id is different upon every reservation, so I must request it.) Whent the operator enters the ID, I perform the update, and unlock the record.

    This solution provides the most assurance. That is, as soon as someone says they want it, it's made inactive so that someone can use it. It worked great. However, there was a design problem: if the "get client id" dialog box is never closed (say the client hung up and the operator went to the toilet) then other users trying to lock that record would be deadlocked. It would stay that way until the original client unlocked the record, or until the client or server were shut down.

    That's no good! So I no longer lock the record until the "get client id" dialog box is closed. This means that you run the risk of getting out-reserved by another operator who is faster at typing, but it means no deadlock.

    From my choices.txt file:

    * Originally when a client wanted to reserve a record, I'd allowed
    the record to be locked before the GUI displayed a dialog box
    requesting the customer id. This meant, however, that if the user
    opened the dialog box and walked away, the record would be locked
    indefinitely, and so would other clients wanting to reserve that
    record. Instead I changed that piece so that the customer Id must
    be input prior to the record being locked.


    The thing that made me decide this funtionality was somewhat acceptable was because the week I finished up my assignment I tried to make a plane reservation and in between starting the reservation and making my payment, someone had taken the last seat on the flight and I lost the ticket during the process.


    SCJP 1.4 (91%)<br />SCJD 1.4 (376/400, 94%)
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Robert and Oliver,

    Robert, the scenario you describe supposes a "fat client" design, while Oliver chose the "thin" one (db and business tiers server-side).

    Oliver, indeed, your design avoids any deadlock to occur because of a crashed client.

    As far as your second question is concerned, Anton replied already.

    Regards,

    Phil.
    [ July 26, 2004: Message edited by: Philippe Maquet ]
    Oliver Rensen
    Ranch Hand

    Joined: Jul 23, 2004
    Posts: 109

    Hi all,

    thank you for your quick answers!

    Anton: Your deadlock-definition sounds good, but I think my question "I don't understand, how a deadlock can occur" was a little bit misleading. It would be better to ask "I don't understand, whether a deadlock can occur in my design", because there are many discussions and solutions in this forum to prevent deadlocks. Thus, I was not sure whether I must implement explicitly one of these "deadlock preventing solutions".

    Robert: Sorry to hear that you have lost the last ticket from a flight (I suspect this program was a bad implementation from the FBNS-assignment).
    Your dialog-box to insert the client-id is an interesting design-choice. I think about another way to insert the client-id: a text-field in the main-GUI. But I'm not sure whether I should use a text-field or a dialog-box. The dialog-box looks better. But to handle a text-field in the main-GUI is easier to program (I'm a lazy guy, I know). Why do you have choosen the dialog-box rather than a simple text-field?

    Phil: It's good to hear from the Javaranch-deadlock-expert that my design avoid any deadlocks.
    Some months ago you wrote following to prevent deadlocks: "Allowing multiple locks per client, but publish a locking contract (in your Javadoc) that requires from clients that multiple locks are claimed in some specific order (ascending on recNo for instance). And you don't enforces the contract by code (the only thing you do is writing 2 sentences in your Data javadoc)".
    Only to play it safe: Is it correct, that I don't need this contract in my javadoc?

    Regards

    Oliver
    Anton Golovin
    Ranch Hand

    Joined: Jul 02, 2004
    Posts: 476
    Originally posted by Oliver Roell:
    Anton: Your deadlock-definition sounds good, but I think my question "I don't understand, how a deadlock can occur" was a little bit misleading. It would be better to ask "I don't understand, whether a deadlock can occur in my design", because there are many discussions and solutions in this forum to prevent deadlocks. Thus, I was not sure whether I must implement explicitly one of these "deadlock preventing solutions".

    a)

    1. Client A locks record 1.
    2. Client B locks record 2.
    3. Client A try to lock record 2 and wait().
    4. Client B try to lock record 1 and wait().

    b)

    try {
    long lockCookie = data.lock(recNo);
    data.update(recNo, data, lockCookie);}
    catch (Exception ex) {
    throw ex;
    }
    finally {
    data.unlock(recNo, lookCookie);
    }




    a)

    This is the perfect deadlock scenario. The reason it is a perfect deadlock scenario is because, having acquired a lock, client tries to ackquire a second lock without releasing the first one. That is the classic definition of possible deadlock. There is not way to tell if step 3 is ever going to complete, and the same about step 4. What if Client A never releases lock on record 1 and Client B never releases lock on record 2? Client A and Client B may wait forever.

    b)

    I think there might be a problem with the code. If you throw an Exception from within the catch block, finally will not to execute because control is transferred elsewhere. Therefore, the record is never unlocked. Finally is not guaranteed to always execute, by the way, especially if there is an exception thrown from catch or there is a return statement in try or catch. (Was I wrong here. )

    [ July 25, 2004: Message edited by: Anton Golovin ]
    [ July 26, 2004: Message edited by: Anton Golovin ]
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Anton,

    If you throw an Exception from within the catch block, finally will not to execute because control is transferred elsewhere. Therefore, the record is never unlocked. Finally is not guaranteed to always execute, by the way, especially if there is an exception thrown from catch or there is a return statement in try or catch.


    This is false. You can run this little test to check it:



    BTW and AFAIK, the only way to avoid a finally block to get executed is calling System.exit().

    Regards,

    Phil.
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Oliver,

    You have basically two scenarios which may lead to a deadlock:

    1) a client crashes while holding (a) lock(s);
    2) crossed lock claims as Anton explained.

    Your thin client approach only prevents scenario 1 to happen.

    Regards,

    Phil.
    Anton Golovin
    Ranch Hand

    Joined: Jul 02, 2004
    Posts: 476
    I learn something new everyday. Both rethrown exception and return still have finaaly execute. I wonder what happens after finally executes: does control get transferred as expected?


    [ July 26, 2004: Message edited by: Anton Golovin ]
    Oliver Rensen
    Ranch Hand

    Joined: Jul 23, 2004
    Posts: 109

    Hi Phil,
    hi Anton,

    thank you for your help.

    I think I'll write the mentioned contract in the javadoc to avoid crossed locks.

    But I'm always not sure what could happen that thread 1 or 2 in the above example are never come back to unlock the records. When the server hangs up or the db-file is corrupt, then it could be, that record 1 or 2 never will unlocked, but in this case the deadlock is secondary, because the complete application would not work, and I must either reboot the server or fix the database. Anyway, with the javadoc-contract I should be safe, isn't it?

    Regards,
    Oliver
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Anton,
    I learn something new everyday.

    Me either...
    Both rethrown exception and return still have finaaly execute.

    The code above doesn't demonstrate the return, but yes.
    I wonder what happens after finally executes: does control get transferred as expected?

    It is.

    Regards,

    Phil.
    [ July 26, 2004: Message edited by: Philippe Maquet ]
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Oliver,

    But I'm always not sure what could happen that thread 1 or 2 in the above example are never come back to unlock the records.


    It's easy for you to check Anton's scenario above: just instantiate two threads (T1 and T2), make T1 grab a lock on recno 1 and then wait 1 second before trying to grab a lock on recno 2, while T2 starts to wait half a second, then grabs a lock on recno 2, waits 1 second, and finally tries to grab a lock on recno 1. Deadlock guaranteed!

    Regards,

    Phil.
    Robert Konigsberg
    Ranch Hand

    Joined: Jun 23, 2004
    Posts: 172
    From Philipe:

    Robert, the scenario you describe supposes a "fat client" design, while Oliver chose the "thin" one (db and business tiers server-side).

    Whoops! Good point.
    From Oliver:

    Your dialog-box to insert the client-id is an interesting design-choice. I think about another way to insert the client-id: a text-field in the main-GUI. But I'm not sure whether I should use a text-field or a dialog-box. The dialog-box looks better. But to handle a text-field in the main-GUI is easier to program (I'm a lazy guy, I know). Why do you have choosen the dialog-box rather than a simple text-field?

    Yeah, that would have been a good way if I knew that no more elements would be to the panel. But what do you do if other dialog box functionality needed to be added later on? Suddenly the screen becomes cluttered with many more graphic elements. Plus, doing dialog boxes is easy once you do one -- the second one is always similar, with similar fields, and that's it, you know?
    Oliver Rensen
    Ranch Hand

    Joined: Jul 23, 2004
    Posts: 109

    Phil: Thank you for the deadlock-tip. That's the case I have searched for. I will test it, when my Data-class is completed.

    Robert: I know what you mean, and I'll think about it. Thanx for your suggestion.

    Regards,

    Oliver
    Reza Rahman
    author
    Ranch Hand

    Joined: Feb 01, 2005
    Posts: 580
        
        5
    Oliver:

    Actually, your thin client approach to avoiding deadlocks is still perfectly valid, by virtue of the fact that each "update/delete" request will be on separate threads albeit parallel threads. As long as you are consious about the finally block executing, you will be just fine.

    Deadlocks are something that are more of a problem for a thick client because the lock-unlock sequence is not transactional, as seems to be the examples that are being provided...

    Reza


    Independent Consultant — Author, EJB 3 in Action — Expert Group Member, Java EE 6 and EJB 3.1
    Frans Janssen
    Ranch Hand

    Joined: Dec 29, 2004
    Posts: 357
    Reza,

    Just a question: why do you answer threads that haven't had any traffic for almost a year? Chances that the original posters will read your replies are very slim, I think.

    Frans.


    SCJP 1.4, SCJD
    Reza Rahman
    author
    Ranch Hand

    Joined: Feb 01, 2005
    Posts: 580
        
        5
    Frans:

    I was very excited to see this thread and hoped it would spark renewed interest on the topic (as it did ). Do you know anything that would seem to contradict my assertion? Thanks for sharing your thoughts...

    Reza
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: How can a deadlock occur in a thin client?