Java, Lock, Condition - Signal not waking waiting thread

I have a problem with which i am stuck for some hours and I don't really know how to solve it. It's quite simple - i have some threads, one of them needs to wait for signal from the other one. Somehow, even if I make signal on a condition... nothing happens! It looks like thread is still sleeping. It's really strange issue, but it may be my fault that I don't understand something well...

Here is part of my code:

@Override
public void bodyProduced() {
    lock.lock();
    producedBodies++;
    if (producedEngines == 0) {
        while(producedEngines==0)
        {
            System.out.println("I am still waiting!");
            body.awaitUninterruptibly();
        }
        System.out.println("I waked up!");
        producedBodies--;
        producedEngines--;
    } else {
        engine.signalAll();
    }
}

I am sure that body.signalAll(); is called when there are threads waiting on that condition - I checked and debugger goes over that line many times. However, the line "I am waiting" appears only once for thraad, and "I waked up" never..

Any ideas, how to fix it, or what to check? I tried almost everything...

Thanks for your time and help!

Upvotes: 0

Views: 1357

Answers (2)

adhg
adhg

Reputation: 10883

When you use ReentrantLock you must call the unlock() after your critical section. This must be done in a finally clause

lock.lock();
try{
 // critical section code (may throw exception)
} finally {
  lock.unlock();  
}

If you don't do it (like in your code), no thread will be able to enter this section because it assumes (correctly) that this section is still locked. You have to explicitly unlock it to allow other thread get in.

Upvotes: 3

Matthias
Matthias

Reputation: 2775

if you use a shared lock, you will probably also need to release it at some point. otherwise only the first thread will be able to go past the first line and the other threads will stop waiting for the lock to be freed.

Also your increments and decrements of producedBodies and producedEngines will probably not work really well once you fix the lock thing as long as they are not volatile.

anyways, concurrency always is a hard topic and it is generally a very good practise to not write such code by yourselve. Whenever you think, you've solved a concurrency problem, you're most likely only seeing the tip of the iceberg.

in your case, my I recommend, considering the use of Synchronized, CountDownLatch or maybe ExecutorServices? (You have not really described the problem you have clearly). If none of the features coming with the JDK work for you, then please also have a look at Heinz Kabutz's java newsletter because that guy knows how to work with concurrency.

Upvotes: 2

Related Questions