0

In Java, why is unlocking called (lock.unlock()) after calling signal (notEmpty.signal() and notFull.signal())?

The order is reversed in pthread. So why is the difference? Thanks.

From The Art of Multiprocessor Programming,

1 class LockedQueue<T> {
2     final Lock lock = new ReentrantLock();
3     final Condition notFull = lock.newCondition();
4     final Condition notEmpty = lock.newCondition();
5     final T[] items;
6     int tail, head, count;
7     public LockedQueue(int capacity) {
8         items = (T[])new Object[capacity];
9     }

10     public void enq(T x) {
11         lock.lock();
12         try {
13             while (count == items.length)
14                 notFull.await();
15             items[tail] = x;
16             if (++tail == items.length)
17                 tail = 0;
18             ++count;
19             notEmpty.signal();
20         } finally {
21             lock.unlock();
22         }
23     }

24     public T deq() {
25         lock.lock();
26         try {
27             while (count == 0)
28                 notEmpty.await();
29             T x = items[head];
30             if (++head == items.length)
31                 head = 0;
32             --count;
33             notFull.signal();
34             return x;
35         } finally {
36             lock.unlock();
37         }
38     }
39 }
  • This is really one question, you can edit your original if you want to add something instead of posting new questions and cross linking them. – pvg Oct 16 '17 at 12:40
  • (1) One is about pthread and the other about java. Not many people are familar with both. If I merged them, then you would probably request me to separate, citing that there are too many questions in a post, as you often did. Either way, I can't please you. (2) the site doesn't allow me to add to the original post. Saying too much code, so I can't –  Oct 16 '17 at 12:42
  • The question is really about both and you can extract and reduce the relevant bits of code instead of posting giant blobs. If the questions were not related you wouldn't need to cross link them like that. Two bad questions is really more than twice as bad as one well-written question. Read [ask] and [mcve] – pvg Oct 16 '17 at 12:44
  • It does mean that if your question can't be answered without reading your other, nearly identical question. When the site is complaining at you about the size of your question, it's telling you something about the quality of your question for the site and essentially asking you to edit, not to open a new question so you can work around the restriction. – pvg Oct 16 '17 at 12:47
  • They are halves of the same question because you didn't make the question you wanted to ask succinct enough for the site not to barf. They are _one question_. You can't answer one fully without reading the other. – pvg Oct 16 '17 at 12:58

1 Answers1

-1

Edit: Condition can be considered as wrapper for Object. But it is more, because it is connected with lock. But like in Object, there are 2 methods, wait() (await()) for work, and notifyAll() (signal()) the work is done. Look at this stack answer Why should the notify method be inside a synchronized block?

In the code you provided, there are some cases, when thread cannot continue. If the queue is full, and you want to add element, then it cannot proceed. You can do this without await(), and signals(), but then your code would have to return fail, or throw exception for example QueueIsFullException.

Callers of the code want to have an easy interface. They want to just put element in, instead of doing while loop and trying to insert element (busy spinning, cpu intensive). Thats why there is await and signal (wait until ready, without consuming CPU).

So when thread1 is stuck waiting for a place to insert element (await on line 14), it releases the lock, and other threads are free to obtain it.

When thread2 takes the element, it signals to thread1, that queue is not full. So when thread2 unlocks, thread1 reacquires the lock.

mlecz
  • 985
  • 11
  • 19
  • Thanks. I am also wondering why the order is reversed for pthread. see the link in my post. Thanks. –  Oct 16 '17 at 12:47