Prev: create a string of <n> equal chars <c>
Next: Possible easy diagnostic outputting from multiple threads tothe one text frame
From: Christian Kaufhold on 13 Jul 2010 16:47 Lew <lew(a)lewscanon.com> wrote: > markspace wrote: >> Here's an example. This class is, I believe, thread-safe, >> although quite simple. >> >> class TextAreaHandler extends Handler { >> @Override >> public void publish( LogRecord record ) >> { >> view.append( record.getMessage() ); >> view.append( '\n' ); Must be done atomically: view.append(record.getMessage() + '\n'); >> >> >> } >> > > I worried about the 'view.append()' actions seeming not to be on the > EDT until I looked at the Javadocs for 'JTextArea#append()': > "This method is thread safe, although most Swing methods are not. > Please see _Threads and Swing_ for more information." The documentation is wrong, as has been discussed already years ago, mostly in comp.lang.java.gui Even with optimistic eyes, the state of affairs is: 1. You /may/ call 'append' from any thread at the same time (assuming an underlying Document that supports it, but typically one does not use custom Documents for a JTextArea, and the default one does). 2. But it need not insert the new text /at the end/ (there may be a thread switch between the call to Document.getLength() and Document.insertString()) 3. If you also /remove/ from the Document and not only insert new text, then 'append' may silently fail instead of inserting text at all (same reason as 2; the BadLocationException that is thrown in such a situation is silently ignored in append.)
From: Christian Kaufhold on 13 Jul 2010 17:48
markspace <nospam(a)nowhere.com> wrote: > Christian Kaufhold wrote: > >> Lew <lew(a)lewscanon.com> wrote: >>> I worried about the 'view.append()' actions seeming not to be on the >>> EDT until I looked at the Javadocs for 'JTextArea#append()': >>> "This method is thread safe, although most Swing methods are not. >>> Please see _Threads and Swing_ for more information." > >> The documentation is wrong, as has been discussed already years ago, mostly >> in comp.lang.java.gui > > > You appear to be correct. How odd. > > Even ignoring problems with mutual exclusion and stuff happening "at the > same time", the calls append() and setText() make no attempt at > synchronization or any sort of happens-before relationship. The > underling call to Document.insert isn't noted to be thread safe either, > so I don't know what prompted the Swing team to mark this method as > thread safe. > > (OTOH, the underlying Document doesn't have the usual Swing note about > not being thread safe, so perhaps the entire class is thread safe. Not > sure. There's nothing on thread safety documented at all for Document, > either way.) Document has render(Runnable), which says something about about concurrency, basically the code inside the runnable is called while being read-locked, "if the model supports being updated asynchronously". (This is actually never(?) used by actual Swing code, instead it uses AbstractDocument.readLock/-Unlock and does not support concurrency at all for non-AbstractDocument.) Without a way to obtain a also a write-lock, potential concurrency support is of little use, as the signatures of insertString and remove are such that one cannot ever call them in a thread-safe way, except for insertString(0, ...), and pointless remove(0, 0). (It would be different if these took Position arguments, with Position previously created from within the readLock). So, Document alone is insufficient. In fact, then, AbstractDocument has writeLock/-Unlock (but protected, so of little use-in-itself). With that at hand, it is not so bad, you can at least write from a background thread to a Document readonly in the JTextComponent; there was at least one problem with a deadlock, but that was several Java versions ago: http://groups.google.com/group/comp.lang.java.gui/browse_thread/thread/414d29ef346afaf3/432fadae23e3947a?q=access+component+lock+kaufhold#432fadae23e3947a |