Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Another "current thread not owner" problem  RSS feed

 
Steve Dyson
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a similar problem to others posted here but cannot see how to cure it.

I have created an inner class to handle events by maintaining thread to run the event handler. (I have designed it this way as I actually have a Vector of threads so I can de-couple the event handlers).

It seems to work as expected if I use sleep(100) to pause the thread but if I use wait() then I get the "current thread not owner" exception...


private class ProcessEvent extends Thread
{
public ProcessEvent(final IfCtuInputEventListener listener)
{
super();
setDaemon(true);
this.listener = listener;
}

//----------------------------------------------------

// queueEvent is called when by the input handler.

public void queueEvent(CtuInputEvent event)
{
eventQueue.add(event);
synchronized (eventQueue)
{
eventQueue.notify();
}
}

//----------------------------------------------------

public void run()
{
log.debug(COMPORTSTR + "Starting ProcessEvent run-forever loop");
try
{
while (loopForever)
{
// Loop processing any complete lines received.
while( eventQueue.size() > 0 )
{
CtuInputEvent event = eventQueue.removeFirst();
listener.inputMessageHandler(event);
}
synchronized (eventQueue)
{
eventQueue.wait();
// sleep(100);
}
}
}
catch (Exception e)
{
log.error(COMPORTSTR + "Forced out of ProcessEvent " + e);
e.printStackTrace();
}

}

private final LinkedList<CtuInputEvent> eventQueue = new LinkedList<CtuInputEvent>();
final IfCtuInputEventListener listener;
}


Any suggestions please!

Steve.

[ October 05, 2006: Message edited by: Steve Dyson ]
[ October 05, 2006: Message edited by: Steve Dyson ]
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24215
37
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Steve,

Welcome to JavaRanch!

Your code looks fine to me (well, not so much, actually -- see below -- but the wait/notify part is fine.) Did you examine the stack trace and make sure that it's the wait() call shown below that throws the exception? Because I can't see how that could happen in this code.

As for the not-so-much part: you've got a LinkedList being modified and read by different threads outside of a synchronized block. This is very likely to lead to data loss and/or corruption of the list. There's really no way to fix this other than expanding the synchronized blocks to cover all the list usage.
 
Steve Dyson
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ernest,

Thanks for such a rapid response. It got me thinking...

1)You are absolutely right, I should have both the eventQueue.add() and the eventQueue.removeFirst() calls within synchronised blocks. This was a disaster waiting to happen! Thanks for pointing that out.

2)I don�t understand how the eventQueue.wait() and the eventQueue.notify() calls will work if they are (both) within synchronised blocks! If the wait(0 is within a synch block then the call to notify() would be blocked! If the notify() is not within a synch block then what is the point of having the wait() in a synch block? I have just disappeared in my own puff of logic!

So for the meantime I am using the code:

. public void queueEvent(CtuInputEvent event)
. { // Called from separate thread.
. synchronized (eventQueue)
. {
. eventQueue.add(event);
. }
. }
.
.
. public void run()
. {
. CtuInputEvent event;
. try
. {
. while (loopForever)
. {
. while( eventQueue.size() > 0 )
. {
. synchronized (eventQueue)
. {
. event = eventQueue.removeFirst();
. }
. listener.inputMessageHandler(event);
. }
. sleep(100);
. }
. }
. catch (Exception e)
. {
. log.error("Forced out of ProcessEvent " + e);
. e.printStackTrace();
. }
. }




Any/all criticisms/suggestions gratefully received. Thanks.

Steve.
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24215
37
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Regarding the puff of logic: wait() releases the monitor of the object you call it on; it's an "escape hatch" from a synchronized block or method.

Regarding resigning yourself to using "sleep()": don't give up using wait() too easily. I'd feel better if we understood where the problem was coming from -- and you'd probably learn something from solving it, too.
 
Steve Dyson
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest,

Thanks again for your help. I changed the code (as shown below) and the error has not represented ifseelf. There were a few minor changes elsewhere in the test program and I guess one of these caused the error.

On the positive side it seems I now have two working solutions. On the negative side I am not at all clear at how the problem was solved.

Nevertheless it has been an interesting and insightful introduction to the joys of threading!

Thanks
Steve.

. public void queueEvent(final CtuInputEvent event)
. {
. . synchronized (eventQueue)
. . {
. . . eventQueue.add(event);
. . . eventQueue.notify();
. . }
. }
.
.
. public void run()
. {
. . CtuInputEvent event;
. . try
. . {
. . . while (loopForever)
. . . {
. . . . while( eventQueue.size() > 0 )
. . . . {
. . . . . synchronized (eventQueue)
. . . . . {
. . . . . . event = eventQueue.removeFirst();
. . . . . }
. . . . . listener.ctuInputEventHandler(event);
. . . . }
. . . . synchronized (eventQueue)
. . . . {
. . . . . eventQueue.wait();
. . . . }
. . . }
. . }
. . catch (Exception e)
. . {
. . . log.error("Forced out of ProcessEvent " + e);
. . . e.printStackTrace();
. . }
. }
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!