<AWT Dev> [9] Review Request: 8165769 Hang in the help menu item

Semyon Sadetsky semyon.sadetsky at oracle.com
Wed Nov 16 16:21:10 UTC 2016



On 16.11.2016 17:52, Sergey Bylokhov wrote:
> On 16.11.16 17:32, Semyon Sadetsky wrote:
>>> There are a few issues which can cause a hang in some of our menu
>>> stress tests:
>>>  - Lack in synchronization in the Menu, we tried to synchronized the
>>> write of fields, but skip synchronization when we read the fields(in
>>> getters for example). In the fix most of the fields were marked as
>>> final(if possible) or volatile.
>> Since the synchronized blocks cannot be simply omitted the adding
>> volatile keyword to the fields doesn't improve multithreading capability
>> of menu components and the most of the proposed changes practically
>> useless.
>
> Please clarify the statement above.
I can give you an example:

CheckboxMenuItem.java

  243     public synchronized void addItemListener(ItemListener l) {
  244         if (l == null) {
  245             return;
  246         }
  247         itemListener = AWTEventMulticaster.add(itemListener, l);
  248         newEventsOnly = true;
  249     }

we are enabling event by calling the method above on thread A. The 
method is synchronized.

at the same time on thread B dispatchEventImpl(AWTEvent e) is called 
which is not synchronized at all.
If thread A is paused by the scheduler at line 248 then thread B may be 
executed and the event will be skipped in dispatchEventImpl(AWTEvent e) 
because of newEventsOnly=false still.
By making newEventsOnly and itemListener fields volatile you only 
guarantee their visibility for thread B but this doesn't make 
newEventsOnly change atomic along with adding an item listener.

Same for enableEvents(long eventsToEnable) method.
>
>>
>> Changing package private accesses to private in general improves
>> encapsulation and may be approved. But multithreading issues should be
>> fixed differently.
>> Actually the MenuComponent appContext field is never changed according
>> to its spec:
>> /**
>>      * The {@code AppContext} of the {@code MenuComponent}.
>>      * This is set in the constructor and never changes.
>>      */
>>     transient AppContext appContext;
>>
>> I suggest to declare it final and also this will be enough to make it
>> thread safe.
>
> But in some corner cases we change this value, so it cannot be final.
What is that corner case? The comment clearly states that it is never 
changed.
>
>>
>> Note that Component appContext field can be changed and this
>> multithreading issue should be resolved. Since the filed is accessed
>> only using the component accessor it should be enough to synchronize the
>> corresponding getter and setter.
Also it seems Menu#isHelpMenu field is never used except for toString() 
and may be removed.
>>
>> --Semyon
>>>  - When the submenu is removed from Menu/MenuBar we do not reset its
>>> parent field if the Menu/MenuBar have peer==null. So if later we tried
>>> to call MenuBar.setHelpMenu(submenu) we skip this submenu because we
>>> think it was added already.
>>>
>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8165769
>>> Webrev can be found at:
>>> http://cr.openjdk.java.net/~serb/8165769/webrev.00
>>>
>>
>
>



More information about the awt-dev mailing list