1

My question is this: How do you hold the lock on a parent for the duration that a nested child is active?

I am writing a multithreaded Java application using the Codename One development framework where I have a parent class and a nested child class. The purpose of the child class is to act as an iterator over a Vector. Now my understanding is that while the iterator is running, the vector cannot be changed.

Here's a very simple code example:

public class Parent<E> implements Collection<Object> {

    private Vector<Object> objectCollection;

    Parent() {
        this.objectCollection = new Vector<Object>();
    }

    public Child<Object> iterator() {
        return(new Child());
    }

    class Child implements Iterator<Object> {

        private int index;

        Child() {
            this.index = 0;
        }

        public boolean hasNext() {
            int size = this.objectCollection.size()
            if (size <= 0) return(false);
            if (this.index >= size) return(false);
            return(true);
        }

        public Object next() {
            Object temp = objectCollection.elementAt(this.index);
            this.index++;
            return(temp);
        }
    }

}

What I want to do is while the nested class (iterator) is instantiated, I want the parent instance locked so all other threads coming into the parent will be blocked until the thread that has the iterator is finished and releases it.

I have done some searching on this and found these questions:

Locking and synchronization between outer and inner class methods?

Acquiring inner-class lock using outer-class locks?

Programming a mutex in Java

Is there a Mutex in Java?

However, these do not exactly match my scenario. The only thing that I can think of is to use a spinlock, but that's also not recommended in Java. So basically, I am looking for a way to do this. I can code it, I just need an explanation of what to do.

EDIT:

Only one thread would have access to the iterator. I am trying to stop the parent from being modified while the iterator is active.

Daniel Rudy
  • 1,411
  • 12
  • 23
  • Can you define "active"? I don't think iterators are the right model for what you are trying to do. – markspace Mar 07 '18 at 03:21
  • How many elements will this vector have and how often will it be modified? [CopyOnWriteArrayList](https://docs.oracle.com/javase/8/docs/api/?java/util/concurrent/package-summary.html) might be a better match. – markspace Mar 07 '18 at 03:25
  • I define active as having references to the object. – Daniel Rudy Mar 07 '18 at 04:01
  • Java can't detect when an object goes out of scope. The garbage collector usually runs much later, so an "in-active" object might be sitting around for a long time (possibly forever) before the GC gets around to it. The only thing I can think of (besides using different requirements) is to add a method call to the iterator to release its resources (and lock). – markspace Mar 07 '18 at 04:56

2 Answers2

1

I think ReentrantReadWriteLock can implement your scenes; but you should use write lock when update the collection; use read lock when iterate the collection;

Tonney Bing
  • 230
  • 2
  • 9
0

There is EasyThread which allows you to do these things really easy:

private Iterator createIterator() {
   if(!easyThread.isThisIt()) {
      Iterator i = easyThread.run(() -> return createIterator());
      return i;
   }
   // create the iterator
}

What's happening here is that all the code within "create the iterator" will run within the thread handled by EasyThread.

Shai Almog
  • 51,749
  • 5
  • 35
  • 65