Re: svn commit: r707569 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/ObjectContextStateLog.java test/java/org/apache/cayenne/remote/CayenneContextDeletionTest.java

From: Andrey Razumovsky (razumovsky.andre..mail.com)
Date: Fri Oct 24 2008 - 07:47:26 EDT

  • Next message: Ricardo Ghisi Tobaldini (JIRA): "[jira] Commented: (CAY-1125) MySQL SMALLINT UNSIGNED is mapped as java.lang.Short, should be java.lang.Integer"

    The problem is NOT that some list is accessed by multiple threads. The
    problem is that java throws ConcurrentModificationException when you delete
    an object from the list while iteration over it. Two solutions I know from
    my experience are:
    1. First do operations, and afterwards delete (done in the code).
    2. Iterate through array with simple loop (e.g. for (int i = 0; i <
    list.size(); i++) - this helps in your case, because we have only one
    modification thread, but still I don't trust this code somewhy and try to
    avoid it. Also here we'll need to manually change the index (i-- when
    element is deleted).

    Also note that there is just ONE thread accessing to the list, so all
    synchronization is useless and may result in deadlock!

    2008/10/24, Tore Halset <halse..vv.ntnu.no>:
    >
    > Hello.
    >
    > I do not know if there is a List in java.util.concurrent, but it would be
    > nice if we could use one from there.
    >
    > Another option that seem to be preferred over Vector these days is
    >
    > Collections.synchronizedList(new ArrayList())
    >
    > Regards,
    > - Tore.
    >
    > On Oct 24, 2008, at 13:20 , Kevin Menard wrote:
    >
    > Just as a heads up, we can use the new Java5 concurrent classes. I
    >> don't think we have in the codebase, yet, but there's nothing stopping
    >> us from doing so. Note that I haven't really looked at the problem
    >> and if a Vector is the best fit, then that's fine, too.
    >>
    >> --
    >> Kevin
    >>
    >>
    >>
    >> On Fri, Oct 24, 2008 at 3:13 AM, <andre..pache.org> wrote:
    >>
    >> Modified:
    >>> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextStateLog.java
    >>> URL:
    >>> http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextStateLog.java?rev=707569&r1=707568&r2=707569&view=diff
    >>>
    >>> ==============================================================================
    >>> ---
    >>> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextStateLog.java
    >>> (original)
    >>> +++
    >>> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContextStateLog.java
    >>> Fri Oct 24 00:13:36 2008
    >>>.. -23,7 +23,9 @@
    >>> import java.util.Collection;
    >>> import java.util.Collections;
    >>> import java.util.HashSet;
    >>> +import java.util.List;
    >>> import java.util.Set;
    >>> +import java.util.Vector;
    >>>
    >>> import org.apache.cayenne.graph.GraphChangeHandler;
    >>> import org.apache.cayenne.graph.GraphManager;
    >>>.. -52,6 +54,11 @@
    >>> * Updates dirty objects state and clears dirty ids map.
    >>> */
    >>> void graphCommitted() {
    >>> + /**
    >>> + * Array for deleted ids, to avoid concurrent modification
    >>> + */
    >>> + List deletedIds = new Vector();
    >>> +
    >>> for (Object id : dirtyIds) {
    >>> Object node = graphManager.getNode(id);
    >>> if (node instanceof Persistent) {
    >>>.. -62,11 +69,19 @@
    >>>
    >>> persistentNode.setPersistenceState(PersistenceState.COMMITTED);
    >>> break;
    >>> case PersistenceState.DELETED:
    >>> + deletedIds.add(id);
    >>>
    >>> persistentNode.setPersistenceState(PersistenceState.TRANSIENT);
    >>> break;
    >>> }
    >>> }
    >>> }
    >>> +
    >>> + /**
    >>> + * Now unregister all deleted objects
    >>> + */
    >>> + for (Object id : deletedIds) {
    >>> + graphManager.unregisterNode(id);
    >>> + }
    >>>
    >>> clear();
    >>> }
    >>>
    >>
    >>
    >



    This archive was generated by hypermail 2.0.0 : Fri Oct 24 2008 - 07:47:55 EDT