Is this your first time here? SwingWiki is a Java Swing Developer community site with an big archive of Swing-related usenet groups and mailing lists, but also tips, tricks and articles and book reviews written by your colleagues from around the world. If you came here through a search engine and did not find what you were looking for, make sure to check the wiki table of contents.

Table of Contents

Thread-safe listener processing

Always think about concurrency when dispatching an event to listeners. During the event dispatching, some new listeners might register themselves, and some old listeners might ask to be removed. So, never use an iterator directly on your list of listeners - because iterators become invalid when the list changes.

Synchronizing listener processing methods might seem as a solution, but it can lead to several problems - first of all, you are unreasonably blocking other application threads (that try to add or remove listeners), and you can cause a deadlock (if a listener tries to remove itself upon receiving the event - this might look odd at first glance, but it is not so uncommon.).

A good solution is to copy the current listeners to a new list, and use the iterator of that list to dispatch events. Here is an example:

class ArchiveTableModel implements TableModel{
	private List listeners;
	public void addTableModelListener(TableModelListener l) {
		listeners.add(l);
	}
	public void removeTableModelListener(TableModelListener l) {
		listeners.remove(l);
	}
	void replaceData(List messages){
		ArrayList newMessages=new ArrayList(messages);
		this.messages=newMessages;
		fireTableEvent(new TableModelEvent(this));
	}
	private void fireTableEvent(TableModelEvent evt){
		ArrayList listenersCopy=new ArrayList(this.listeners);
		for (Iterator i=listenersCopy.iterator(); i.hasNext(); ){
			((TableModelListener) i.next()).tableChanged(evt);
		}
	}
//other methods

javax.swing.event.EventListenerList automates some of this functionallity, and provides a degree of thread-safety1).

From Java 1.5, there is another option - java.util.concurrent.CopyOnWriteArrayList2). That is a thread-safe version of ArrayList in which all modifications (adding or removing elements) are performed by copying the contents of the array and working on the new copy. Existing iterators are not affected by any changes. From official javadoc - this is ordinarily too costly, but may be more efficient than alternatives when traversal operations vastly outnumber mutations.

see also

External links

1) Thanks to Steven Buroff for this comment
2) Many thanks to Charlie Hayes for this hint
 

Comments? Corrections? Contact us or Login to edit pages directly (registration is free and takes less than displaying a JLabel)
  best/thread-safe_listener_processing.txt · Last modified: 2006/09/29 09:24 by 86.133.133.175 (gojko)
 
Recent changes | RSS changes | Table of contents | News Archive | Terms And Conditions | Register | The Quest For Software++| Ruby Resources

Sedo - Buy and Sell Domain Names and Websites project info: swingwiki.org Statistics for project swingwiki.org etracker� web controlling instead of log file analysis