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();
}
}