Search Mailing List Archives

Limit search to: Subject & Body Subject Author
Sort by: Reverse Sort
Limit to: All This Week Last Week This Month Last Month
Select Date Range     through    

[protege-discussion] Frame API synchronization

Timothy Redmond tredmond at
Mon Jun 2 09:59:44 PDT 2008

On May 30, 2008, at 7:34 AM, Len Yabloko wrote:

> Timothy,
> While waiting for your response trying several other ways to make it  
> work I discovered that the problem may be caused by something other  
> than thread lock.

This is an advantage of getting a stack dump as described in [1].  You  
will know exactly what Protege is doing when it "freezes".  Many  
deadlocks are detected.  But you can usually determine the remaining  
deadlocks by noticing that the threads that should be doing real work  
are waiting and don't make progress.  The stack dump also gives an  
initial view of what is actually happening.  This can also work as a  
poor mans performance profiler giving some first look at what routines  
are using up time.

> First I noticed that execution of Protege thread stops at  
> kb.flushEvents(), then I realized that my special thread may result  
> in large number of events for Protege to flush later. So I stopped  
> using my thread and returned to normal single thread, which does no  
> lock but still shows significant delays processing Protege events.  
> The delays increase as I add more instances.

Many times people who have a thread writing to the protege knowledge  
base turn off event generation rather than event dispatch.  They then  
have to tell all the ui components and other knowledge base listeners  
that they need to refresh when the processing is over.  This is often  
more efficient than turning off event dispatch and then making all the  
listeners work through the events when processing is done.

> I also  suspect that frequent frame.setName() may be causing it  
> somehow. I noticed that 3.4 beta builds after 130 replace setName()  
> with rename(). Does it change event processing?

I would not have guessed this in a pre 500 Protege build.  But in the  
latest Protege builds my recommendation would be to avoid using  
rename() if possible.  Try to set the name of the frame correctly when  
it is created if possible.

> Another observation I made is that everything works well when  
> Protege event generation is turned off completely, which also  
> suggest that that may be a root cause of problem. I realize that all  
> that is in-conclusive, but for now without multi-threading and with  
> minimal frame updates it works. I am concerned however about scaling  
> it to large number of frames. Do you have any advise for me?

This is a very common situation.  I think that turning off event  
generation is quite possibly the best approach.  Then you need to  
refresh all the components that were expecting to get their updates  
from the event dispatch.  For the tab widgets this can be done with  
the command


I was sure that I wrote a wiki about this but I couldn't find it.  But  
I did find the following [2] which has most of what we want.



> Thanks
> -Len
>> Sorry for the delayed response.
>> I will need to gather some more information to understand the  
>> problem.
>> I did notice a possible issue.  Usually code that is written as  
>> follows
>>  synchronized (monitor) {
>>    ...
>>    monitor = ...;
>>    ...
>>  }
>> is incorrect.  This code allows two threads to be in the synchronized
>> block at the same time. Consider the following sequence:
>>   1. Thread 1: monitor = o1
>>   2. Thread 1: enters the synchronized block holding the lock o1
>>   3. Thread 1: changes the value of monitor to o2
>>   4. Thread 2: enters the synchronized block holding the lock o2
>>   5. Thread 1 and Thread 2 are both in the synchronized block at the
>> same time.
>> Now I did notice that the assignment to monitor was  the last
>> statement in the sequence so perhaps synchronizing on monitor was
>> really what you wanted?  Even so this is a tricky way to write this
>> code.
>> So to move further I need two different kinds of information.  First
>> you say that Protege froze.  If  so a stack dump of the active  
>> threads
>> almost always shows the cause.  [1] shows how to get this type of
>> stack trace.  It is quite  possible that the stack dump alone would  
>> be
>> sufficient for me to determine what happened.
>> Second, I may also need to know more about how your code is written.
>> In particular, based on what you sent I can't tell how
>> is invoked.  I am guessing that somewhere you have a line like
>> 	(new Thread(monitor)).start()
>> ?  If so then with the outline that you showed it should be true that
>> no locks are held when the kb.flushEvents() call is invoked which is
>> what we required.  It also looks like there is no synchronization of
>> the monitor thread with other threads which is also  helpful for
>> avoiding deadlocks.  Maybe you could attach the portion of your code
>> that invokes the kb.flushEvents()?
>> -Timothy
>> [1]
>> On May 12, 2008, at 2:53 PM, Len Yabloko wrote:
>>> Hi Tania,
>>> Thanks for your suggestion. I am not sure what you mean by "Make
>>> sure that the call to kb.flushEvents() is not holding any locks".
>>> However, using your suggestion I still get deadlocks. It looks to me
>>> that the problem occurs when my thread is trying to turn off Protege
>>> event dispatch while Protege thread (or swing) is trying to process
>>> new events. For example, if I press 'create' button once, then my
>>> thread will create new instance without a problem. But if I click it
>>> twice rapidly, then second click will "freeze" Protege because first
>>> one is still trying to flush events. Note that I use synchronized
>>> blocks with runnable object as thread monitor like this:
>>> synchronized (monitor) {
>>> code
>>> monitor = new Runnable()  {
>>>  public synchronized void run () {
>>>    kb.setDispatchEventsEnabled(false);
>>>    try {
>>>       ... my code creating instances
>>>    } catch {}
>>>    kb.setDispatchEventsEnabled(true);
>>>   ((DefaultKnowledgeBase) kb).flushEvents();
>>>  }
>>> };
>>> }
>>> Do you have any other suggestions?
>>> Thanks
>>> --Len
>>>> Hi Len,
>>>> Thanks for the clarification. From the first email, I did not  
>>>> realize
>>>> that you were creating the instances in a separate thread.
>>>> We have a solution that will probably work. First of all, instead  
>>>> of
>>>> turning event generation on and off, turn event dispatch on and  
>>>> off.
>>>> Make sure that the call to kb.flushEvents() is not holding any  
>>>> locks.
>>>> The code could look like:
>>>> new Thread {
>>>> loop {
>>>>    kb.setDispatchEventsEnabled(false);
>>>>    // make changes to kb ...
>>>>    kb.setDispatchEventsEnabled(true);
>>>>    ((DefaultKnowledgeBase) kb).flushEvents();
>>>> }
>>>> This is very delicate and we are very interested to know how it
>>>> worked.
>>>> Thanks,
>>>> Tim and Tania
>>>> Len Yabloko wrote:
>>>>> Tania,
>>>>> Yes, I am calling API from my special thread that creates
>>>>> instances. The problem I am having is that Protege listeners while
>>>>> updating UI may block somehow any firther API call from my thread.
>>>>> Normaly I turn them off by disabling Protege "generateEvents"
>>>>> while performing my calls. But if I don't do that, then sooner or
>>>>> later (not right away) Protege will lock up. Do you have any
>>>>> advise for me?
>>>>> Thanks,
>>>>> Len
>>>>>> Len,
>>>>>> Are you using the Protege UI and implemented a plugin that create
>>>>>> individuals by calling the API? If so, then you don't need to  
>>>>>> call
>>>>>> wait(), the Protege UI is listening for changes in the knowledge
>>>>>> base
>>>>>> and will refresh accordingly.
>>>>>> Tania
>>>>>> Len Yabloko wrote:
>>>>>>> Hi,
>>>>>>> I am calling frame API to create new instance and expect to see
>>>>>>> GUI updated correspondingly. But I need to wait() until Protege
>>>>>>> GUI completes refresh before issuing another change. What flag
>>>>>>> should I use?  Will GUI issue notifyAll()?
>>>>>>> Thanks
>>>>>>> _______________________________________________
>>>>>>> protege-discussion mailing list
>>>>>>> protege-discussion at
>>>>>>> Instructions for unsubscribing:
>>>>>> _______________________________________________
>>>>>> protege-discussion mailing list
>>>>>> protege-discussion at
>>>>>> Instructions for unsubscribing:
>>>>> _______________________________________________
>>>>> protege-discussion mailing list
>>>>> protege-discussion at
>>>>> Instructions for unsubscribing:
>>>> _______________________________________________
>>>> protege-discussion mailing list
>>>> protege-discussion at
>>>> Instructions for unsubscribing:
>>> _______________________________________________
>>> protege-discussion mailing list
>>> protege-discussion at
>>> Instructions for unsubscribing:

More information about the protege-discussion mailing list