My Swing GUI displays a JList of items that are being sequentially removed by a background thread.
Behind the JList is an ArrayDeque<Card>
, myHopper, implementing myHopper.getSize()
and myHopper.getElementAt()
, as per the contract of an AbstractListModel.
The background thread removes items using myHopper.poll()
.
Not surprisingly, I'm getting AWT array index out of bounds exceptions currently.
What should I be doing to properly synchronize access to myList between the EDT thread and my background thread? I have seen references to Collections.synchronizedList(arrayList)
but I don't think that fits my ArrayDeque.
The short answer to my question appears to be "You can't: you must never attempt to access a Swing component [and that includes its model] from any thread other than the EDT."
This post shows how I eventually solved the problem. A worker thread needs to pull an item from a JList's model, and does so using invokeAndWait()
to schedule that work on the EDT, and then waits until that task is done, and then continues.
Using the synchronized LinkedBlockingDeque didn't work, and I suspect that it's because the EDT makes a nonatomic series of calls to the Deque interface when updating the GUI component. Any change to the model between calls, by another thread, could destroy any assumptions of stability that the EDT is making.
(Perhaps that's what's being hinted at by the persistent "Warning: Swing is not thread safe" that appears throughout the Swing documentation.)