[concurrency-interest] Await...Signal -CatchingIllegalMonitorStateException???

David Holmes dcholmes at optusnet.com.au
Tue Oct 24 16:42:06 EDT 2006


Correction - acquiring the Lock before the signal will ensure that the main
thread has called await() first. See - rushing too much.

David
  -----Original Message-----
  From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of David Holmes
  Sent: Wednesday, 25 October 2006 6:27 AM
  To: David Harrigan
  Cc: concurrency-interest at cs.oswego.edu
  Subject: Re: [concurrency-interest]
Await...Signal -CatchingIllegalMonitorStateException???


  Hi David,

  What you don't do is actually check any state before the await(). Your
code will not work correctly unless the parser thread has to acquire the
Lock before it commences parsing - otherwise it could complete the parsing
and do the signal prior to the main thread doing the await().

  Passing a Lock+Condition is working at the wrong level of abstraction -
those should be encapsulated together with the state that is being checked.

  It seems like what you might have here is a use for FutureTask. Your main
thread will create the FutureTask and do a timed get() to wait for the
result. You pass the FutureTask to your parseThread and it does the actual
parsing and upon completion marks the Future task as done.

  Again this is a rushed response - sorry.

  Thanks for the comments re JCiP :-)

  Cheers,
  David Holmes

  -----Original Message-----
  From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of David
Harrigan
  Sent: Wednesday, 25 October 2006 4:37 AM
  To: dholmes at ieee.org
  Cc: concurrency-interest at cs.oswego.edu
  Subject: Re: [concurrency-interest] Await...Signal -
CatchingIllegalMonitorStateException???


    Hi David,

    I appreciate your email back tremendously, it helps to clarify what I'm
trying to do :-) The thing
    is, I am waiting for a state to happen. The first thread X should wait
(for a certain amount of time)
    until thread Y has done it's job. If Y continues for too long, X should
continue and Y should be
    abandoned, otherwise Y will return in time and X can process the
results.

    I believe this is a good model for Lock, newCondition and await(with
timeout) and signal and
    after the helpful comments back, I'm now passing in the lock as well as
the condition into
    thread Y, which then calls await on the condition, after reacquiring the
lock. Doing it this way
    I now do not get any exceptions.

    Does this feel right to you?

    btw, and this is a shout out to all those who have contributed to Java
Concurrency in
    Practice - what an excellent booK!!!!!! :-)

    -=david=-


    On 10/24/06, David Holmes <dcholmes at optusnet.com.au> wrote:
      David,

      You are misusing await()/signal(). The whole point of Conditions is to
wait for some state to be achieved. Hence you should acquire the lock and
while the state is not what you expect, perform the await(). The thread that
is updating the state will acquire the same lock, update the state and
perform the signal()/signalAll(). You can abstract out the state changes if
the "change" is actually just "event X occurred" - in which case a Semaphore
or CountDownLatch might be suitable as a coordination mechanism.

      Sorry this is a rushed reply and I don't have the cycles right now to
fully understand what you are trying to do.

      Cheers,
      David Holmes
        -----Original Message-----
        From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Mike
Quilleash
        Sent: Tuesday, 24 October 2006 4:21 AM
        To: David Harrigan; concurrency-interest at cs.oswego.edu
        Subject: Re: [concurrency-interest] Await...Signal - Catching
IllegalMonitorStateException???


        I think the call to

        condition.signal();

        in this code will always throw this exception.  You should never be
catching this exception explicitly, it is intended to inform you when you
have a logic error in your use of a condition.  If you look at the docs for
Condition.await()/signal()/signalAll(), it says that the owning lock, in
this case "lock", must be held by the current thread before a call to any of
the above functions.  Failure to do this results in the exception.

        When the X thread is in await() it will release the lock and go into
a wait-state, in this case it will wait until signal() is called on the
Condition or the await() times out.  When this happens it will wake up,
reaquire the lock and continue (you later release the lock again correctly).
It will wait to reacquire the lock if something else holds it.  It is done
this way to avoid race conditions where a call to await() could "miss" a
call to signal().

        In short to avoid the exception you should acquire the lock in your
Parse thread before calling signal() and release it immediatly after in a
finally block.

        Also worth noting that to make a thread sleep for a period of time
Thread.sleep() is better and safer than using synchronized + wait() as it
won't interfere with anything else using "this" as a synchornization object.

        HTH.



------------------------------------------------------------------------
        From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu] On Behalf Of David
Harrigan
        Sent: 23 October 2006 18:46
        To: concurrency-interest at cs.oswego.edu
        Subject: [concurrency-interest] Await...Signal - Catching
IllegalMonitorStateException???


        Hi,

        Firstly let me say that I'm really happy to find this list. I find
threading
        difficult, but I'm trying to get to trips with it as best I can, and
I'm sure
        this list will help my minisule understanding...

        Okay, I am trying to get to trips with the concurrency features in
Java
        1.5, and I've got an issue that I'm trying to understand. I have
this
        basic program structure...

        ....
        ....
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
        ....
        Parser parser = new Parser(condition);
        lock.lock();
        try {
            new Thread(parser).start();
            if(!condition.await(2000, TimeUnit.MILLISECONDS)) {
                if(parser.isReading()) {
                    if(!condition.await(2000, TimeUnit.MILLISECONDS)) {
                        setTimedOutWhilstReading(true);
                    }
                }
                setTimedOutWhilstWaitingForResponse(true);
            }
        } catch(InterruptedException e) {
        } finally {
          lock.unlock();
        }

        then in Parser I have this...

        ....
        ....
        public Parser(final Condition condition) {
            this.condition = condition;
        }

        public void run() {
            try {
               synchronized(this) {
                   wait(10000); // <--------- simulate this parser taking 10
seconds reading, causing timeout in calling thread
               }
            } catch (InterruptedException e) {
            }

            try {
                condition.signal();
            } catch(IllegalMonitorStateException e) {
            }
        }



        Okay, let me try and explain:

        I have a thread (X) that creates a parser (Y). X has to check for a
few things,
        namely that Y hasn't timed out waiting for a response (the first
await in X) then
        if it has timed out X checks to see if Y has started to parse a
response. I've
        simulated in Y that Y takes 10 seconds to do it's business
(ignorning a
        response read etc..I'm just interested in overall time at this
point).

        Now, in X, because the two awaits have timed out (total ~4 seconds),
X has
        moved on and exited out of it's run() and the calling thread of X
does some
        extra things...etc...

        But, because X has moved on, when I call condition.signal() I have
to catch
        an IllegalMonitorStateException! This seems to me a bit "strange." I
can perhaps
        hazzard a guess that because the lock (it's condition) in X no
longer exists, then
        calling condition.signal() in Y causes this, but my question is - is
this correct? Do
        I have to do this? Am I not tripping out?

        Now, the reason I have condition.signal() is that in the version of
Parser that
        does the parsing and returns in < 4 seconds, then X which is sitting
in an
        await state, calling condition.signal() is the right thing to do - I
have to tell X
        that Y is finished....

        What I'm trying to understand is what happens if Y takes a long long
time, what
        I have to do to X (and Y) for the states to be properly managed....

        I hope this is clear? If not, then please do ask me for
clarification...

        Thanks so so much, and I look forward to participating in this list!

        -=david=-

 This e-mail is bound by the terms and conditions described at
http://www.subexazure.com/mail-disclaimer.html


      _______________________________________________
      Concurrency-interest mailing list
      Concurrency-interest at altair.cs.oswego.edu
      http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest




-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20061025/9c5d2895/attachment.html 


More information about the Concurrency-interest mailing list