[concurrency-interest] SwingWorker a special producer/consumer

Rémi Forax forax at univ-mlv.fr
Fri Jun 2 04:25:33 EDT 2006


Pete Soper a écrit :

> Hi Rémi,
>     Nice to see your mail again. Are you looking for a suggestion for 
> a thread-safe queue or the like to pass stuff between your EDT and 
> your main thread?
>
> Regards,
> Pete

The bug reported is not a concurrency bug but
because the implementation must be changed
perhaps the signature of the process() method
can be changed to take a thread safe List or a Queue.

The SwingWorker is clearly a producer/consumer problem :
- i want to put arrays of values (V)
- i want to take all the values in one call.
all in a thread safe way.

The question is what is the best concurrent data structure
for this job.

Rémi Forax

>
> Gregg Wonderly wrote:
>
>>
>> Rémi Forax wrote:
>>
>>> Yesterday, i found a bug in the Sun implementation of the SwingWorker :
>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6432565
>>
>>
>>
>> That bug is not visible yet, can you give specifics?
>
>
> Still in dispatch:
>
> FULL PRODUCT VERSION :
> java version "1.6.0-beta2"
> Java(TM) SE Runtime Environment (build 1.6.0-beta2-b85)
> Java HotSpot(TM) Client VM (build 1.6.0-beta2-b85, mixed mode, sharing)
>
>
> ADDITIONAL OS VERSION INFORMATION :
> Linux localhost.localdomain 2.6.15-1.1833_FC4 #1 Wed Mar 1 23:41:37 
> EST 2006 i686 i686 i386 GNU/Linux
>
>
> A DESCRIPTION OF THE PROBLEM :
> The EDT (Event dispatch Thread) raises a ClassCastException
> with the code below.
>
> Data published by doInBackground() are stored in a list
> and then converted in an array and send to method process()
> in order to reduce synchronization time between EDT and worker thread.
>
> The problem is to determine the class of the array passed to the 
> process()
> method at runtime. Because generics are erased, the class of V is not
> available. The current implementation use the class of the array passed
> as argument of the first call of the method publish() . This is 
> clearly wrong.
>
> Two solutions :
>   - don't use an array in the signature of process() but use a List 
> instead
>   - take the class of V in the constructor.
>     public SwingWorker(Class<T> tClass) {...}
>
> Note : i had reviewed the SwingWorker code when it was integrated to
> mustang (i think a year ago), it troubles me because
> it mix runtime type and generics but i was not able to produce a test 
> case
> that show my insight until today.
> So the test case is not issue from a real application.
>
> Rémi Forax
>
> STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
> run the code
>
> EXPECTED VERSUS ACTUAL BEHAVIOR :
> EXPECTED -
> it should work
> ACTUAL -
> it throws a ClassCastException
>
> ERROR MESSAGES/STACK TRACES THAT OCCUR :
> Exception in thread "AWT-EventQueue-0" java.lang.ArrayStoreException
>     at java.lang.System.arraycopy(Native Method)
>     at java.util.ArrayList.toArray(ArrayList.java:306)
>     at 
> sun.swing.AccumulativeRunnable.flush(AccumulativeRunnable.java:148)
>     at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:96)
>     at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
>     at java.awt.EventQueue.dispatchEvent(EventQueue.java:598)
>     at 
> java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273) 
>
>     at 
> java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183) 
>
>     at 
> java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173) 
>
>     at 
> java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
>     at 
> java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
>     at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
>
>
> REPRODUCIBILITY :
> This bug can be reproduced always.
>
> ---------- BEGIN SOURCE ----------
> import javax.swing.SwingWorker;
>
> public class SwingWorkerTest {
>     public static void main(String[] args) {
>       new SwingWorker<Void,CharSequence>() {
>         @Override
>         protected Void doInBackground() {
>           publish(new String[] {"hello"});
>           publish(new StringBuilder("world"));
>           return null;
>         }
>       }.execute();
>     }
> }
>
> ---------- END SOURCE ----------
>
> CUSTOMER SUBMITTED WORKAROUND :
> Add this line
> publish(new CharSequence[0]);
> as the first line of doInBackground().
> *** (#1 of 1): 2006-05-31 19:56:56 EDT *.*@sun.com





More information about the Concurrency-interest mailing list