3

How to hold multiple locks with wait/notify?

Imagine a situation with two lockable resources: printer and scanner. I ran into deadlock so, I decided to acquire the scanner lock before the printer lock. Now if I want the printer only, I still need to lock the scanner. Here the situation is that one (printing) thread gets to the printer, it notices that another the another (feeding) thread needs to feed paper in. My design calls for the printing thread to wait on the feeding thread to feed paper in.

If I wait on printer. I think I"m still holding the lock on scanner. How could Thread 2 enter the notification code?

What is the commonly used design that would work in this sort of a situation? Say I need to hold 2 locks (to avoid deadlock). How do I do wait/notify with both locks held? Sample code is below.

One obvious method is to invert the lock acquisition order throughout the code and hope that I don't ever need to wait on the scanner.

Is there another way out?

Sample code: Printing Thread:

    synchronized (scanner) {
        synchronized (printer) {
            // action
            while (trayEmpty) {
                printer.wait();
            }
        }
    }

Sample Code for Feeding Thread:

    synchronized (scanner) {
        synchronized (printer) {
            // action
            trayEmpty=false;
            printer.notify();
        }
    }
fodon
  • 4,565
  • 12
  • 44
  • 58
  • possible duplicate of [Java: How can a thread wait on multiple objects?](http://stackoverflow.com/questions/6265225/java-how-can-a-thread-wait-on-multiple-objects) – Keith Randall Jul 23 '12 at 18:10
  • possible duplicate of [Can a thread call wait() on two locks at once in Java (6)](http://stackoverflow.com/questions/3057981/can-a-thread-call-wait-on-two-locks-at-once-in-java-6) – Emil Sit Jul 23 '12 at 18:13
  • I'm not sure that it is a duplicate. I only want to wait on one condition, but in such a way that deadlock is avoided. I"m happy with another paradigm. – fodon Jul 23 '12 at 18:16
  • The trick with locks is to treat them like wedlock. Get rid of the one before you hold another. If you really need two at a time, make sure you don't hold the others when you go to sleep. – fodon Jul 23 '12 at 19:57
  • Why do you need to hold the scanner lock if you are just using the printer? (e.g., in the feeding thread.) – Emil Sit Jul 25 '12 at 15:29

2 Answers2

1
Is there another way out?

Rather than using wait/notify i would suggest you to use Java Concurrent Api explicit Locks there you can lock and unlock in sequence manner

amicngh
  • 7,831
  • 3
  • 35
  • 54
0

One idea for this specific case would be to use a single lock. For example, create a lock object on the object that is at the intersection of row/col (e.g., create a matrix of lock objects).

Emil Sit
  • 22,894
  • 7
  • 53
  • 75