All Downloads are FREE. Search and download functionalities are using the official Maven repository.

test.ca.odell.glazedlists.swing.SimultaneousUpdatesTest Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
/* Glazed Lists                                                 (c) 2003-2006 */
/* http://publicobject.com/glazedlists/                      publicobject.com,*/
/*                                                     O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.swing;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.impl.testing.ListConsistencyListener;
import ca.odell.glazedlists.matchers.AbstractMatcherEditor;
import ca.odell.glazedlists.matchers.Matcher;
import junit.framework.TestCase;

import javax.swing.*;
import java.util.Random;

/**
 * Make sure we can handle multiple updates from different sources.
 *
 * @author Jesse Wilson
 */
public class SimultaneousUpdatesTest extends TestCase {

    /**
     * This test verifies that we can have two threads changing the data and
     * everything will still be consistent as long as proper locks are held.
     */
    public synchronized void testCompetingWriters() {

        // prepare a list with a Swing view
        EventList list = new BasicEventList();
        EvenOrAllMatcherEditor matcherEditor = new EvenOrAllMatcherEditor();
        FilterList filterList = new FilterList(list, matcherEditor);
        EventList swingSafe = GlazedListsSwing.swingThreadProxyList(filterList);

        // make sure everything's always consistent
        ListConsistencyListener.install(swingSafe);

        // write using a background thread
        Thread backgroundThread = new Thread(new AddThenRemoveOnList(list));
        backgroundThread.start();

        // also write using a foreground thread
        try {
            for(int i = 0; i < 500; i++) {
                SwingUtilities.invokeLater(new FilterUnfilter(matcherEditor));
                wait(10);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        // join the other thread to finish up
        try {
            backgroundThread.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private static class FilterUnfilter implements Runnable {
        private EvenOrAllMatcherEditor matcherEditor;
        public FilterUnfilter(EvenOrAllMatcherEditor matcherEditor) {
            this.matcherEditor = matcherEditor;
        }
        public synchronized void run() {
            matcherEditor.setEven();
            matcherEditor.setAll();
        }
    }

    /**
     * Add five values, then remove them.
     */
    private static class AddThenRemoveOnList implements Runnable {
        private final Random dice = new Random(15);
        private EventList list;
        public AddThenRemoveOnList(EventList list) {
            this.list = list;
        }
        public synchronized void run() {
            try {
                for(int j = 0; j < 500; ) {
                    list.getReadWriteLock().writeLock().lock();
                    try {
                        int i = j;
                        j += dice.nextInt(3);
                        for(; i < j; i++) {
                            list.add(new Integer(i));
                        }
                    } finally {
                        list.getReadWriteLock().writeLock().unlock();
                    }
                    wait(10);
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * Match only odd or even values.
     */
    private static class EvenOrAllMatcherEditor extends AbstractMatcherEditor {
        public void setAll() {
            fireMatchAll();
        }
        public void setEven() {
            fireChanged(new EvenMatcherEditor());
        }
        private static class EvenMatcherEditor implements Matcher {
            public boolean matches(Integer item) {
                return item.intValue() % 2 == 0;
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy