<p>The keyset is threadsafe but not its iterator.  The CHM internally caches a keyset instance, so I don't think you really need to cache anything in your code.</p>
<p>Sent from my phone</p>
<div class="gmail_quote">On Feb 16, 2012 5:04 PM, "Adrian Tarau" <<a href="mailto:adrian.tarau@gmail.com">adrian.tarau@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<u></u>

  
    
  
  <div bgcolor="#ffffff" text="#000000">
    Yes, I do. I presumed they are thread safe. There is no mention in
    the keySet method that is not thread safe(or the class
    documentation) and you can easily presume you will get a set that's
    thread safe(including the iterator) since you are using
    ConcurrentHashMap :)<br>
    <br>
    <i>/**<br>
           * Returns a {@link Set} view of the keys contained in this
      map.<br>
           * The set is backed by the map, so changes to the map are<br>
           * reflected in the set, and vice-versa.  The set supports
      element<br>
           * removal, which removes the corresponding mapping from this
      map,<br>
           * via the <tt>Iterator.remove</tt>,
      <tt>Set.remove</tt>,<br>
           * <tt>removeAll</tt>,
      <tt>retainAll</tt>, and <tt>clear</tt><br>
           * operations.  It does not support the
      <tt>add</tt> or<br>
           * <tt>addAll</tt> operations.<br>
           *<br>
           * <p>The view's <tt>iterator</tt> is a
      "weakly consistent" iterator<br>
           * that will never throw {@link
      ConcurrentModificationException},<br>
           * and guarantees to traverse elements as they existed upon<br>
           * construction of the iterator, and may (but is not
      guaranteed to)<br>
           * reflect any modifications subsequent to construction.<br>
           */<br>
          public Set<K> keySet() {<br>
              ....<br>
          }</i><br>
    <br>
    On 02/16/2012 10:26 AM, Vitaly Davidovich wrote:
    <blockquote type="cite">
      <p>Are you sharing the same iterator between multiple threads?
        That's what it sounds like - you can't do that as they aren't
        threadsafe.</p>
      <p>Sent from my phone</p>
      <div class="gmail_quote">On Feb 16, 2012 9:47 AM, "Adrian Tarau"
        <<a href="mailto:adrian.tarau@gmail.com" target="_blank">adrian.tarau@gmail.com</a>>
        wrote:<br type="attribution">
        <blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div bgcolor="#ffffff" text="#000000"> Good morning,<br>
            <br>
            I get recently several failures in one of the processes(a
            remote file collector) which looks like a bug in
            ConcurrentHashMap implementation. I attached all relevant
            code...I do not think I misused the map but... I searched
            for similar complaints but I couldn't find anything relevant
            - <span><a href="http://bugs.sun.com" target="_blank">bugs.sun.com</a></span>
            returns noting when searching for "ConcurrentHashMap
            ArrayIndexOutOfBoundsException".<br>
            <br>
            Thank you,<br>
            Adrian Tarau.<br>
            <br>
            I have a map declared like this:<br>
            <br>
            <small><i>private final Map<Location,
                PriorityBlockingQueue<WorkUnit>>
                workUnitsPerLocation = new
                ConcurrentHashMap<Location,
                PriorityBlockingQueue<WorkUnit>>();</i></small><br>
            <br>
            a work unit is pushed like this:<br>
            <br>
            <small>......<br>
              Queue<WorkUnit> locationQueue =
              getLocationQueue(location);<br>
              boolean offer = locationQueue.offer(workUnit);<br>
              .......<br>
              private Queue<WorkUnit> getLocationQueue(Location
              location) {<br>
                      synchronized (workUnitsPerLocation) {<br>
                          PriorityBlockingQueue<WorkUnit> queue =
              workUnitsPerLocation.get(location);<br>
                          if (queue == null) {<br>
                              queue = new
              PriorityBlockingQueue<WorkUnit>(100, new
              WorkUnit.Comparator());<br>
                              workUnitsPerLocation.put(location, queue);<br>
                          }<br>
                          return queue;<br>
                      }<br>
                  }</small><br>
            <br>
            and a working thread(scheduled to run every 5 seconds) is
            scanning for available work units, peeking one from every
            location(until a maximum number of working units are
            running) like this:<br>
            <br>
            <small><i>class WorkUnitScheduler extends AbstractWorker {<br>
                <br>
                        ...<br>
                        // volatile since the state of the iterator must
                be preserved under different working threads<br>
                        private volatile Iterator<Location>
                workUnitsIterator;<br>
                <br>
                        ....<br>
                <br>
                        private Queue<WorkUnit> getNextQueue() {<br>
                            for (int i = 0; i < 2; i++) {// loop
                twice so we go over all possible locations<br>
                                if (workUnitsIterator == null ||
                !workUnitsIterator.hasNext()) {<br>
                                    workUnitsIterator =
                workUnitsPerLocation.keySet().iterator();//start from
                beginning<br>
                                }<br>
                                while (workUnitsIterator.hasNext()) {<br>
                                    try {<br>
                                        Location location =
                workUnitsIterator.next(); <b><--- fails here</b><br>
                                        if
                (canScheduleFromLocation(location)) {//if allowed, get
                next working unit from this location<br>
                                            return
                workUnitsPerLocation.get(location);<br>
                                        }<br>
                                    } catch (NoSuchElementException e) {<br>
                                        // no location<br>
                                    }<br>
                                }<br>
                            }<br>
                            return null;<br>
                        }<br>
                <br>
                        @Override<br>
                        protected void doRun() {<br>
                                 ....<br>
                                Queue<WorkUnit> queue =
                getNextQueue();<br>
                                if (queue == null) {<br>
                                    break;<br>
                                }<br>
                                WorkUnit workingUnit = queue.poll();<br>
                                if (workingUnit == null) {<br>
                                    continue;<br>
                                }<br>
                                WorkerService.getInstance().schedule(new
                DownloadUploadWorker(workingUnit));<br>
                                ....<br>
                        }<br>
                    }</i></small><br>
            <br>
            and it fails with:<br>
            <br>
            <small><i>got exception
                java.lang.ArrayIndexOutOfBoundsException: 3<br>
                     at
java.util.concurrent.ConcurrentHashMap$HashIterator.advance(ConcurrentHashMap.java:1086)<br>
                     at
java.util.concurrent.ConcurrentHashMap$HashIterator.nextEntry(ConcurrentHashMap.java:1101)<br>
                     at
java.util.concurrent.ConcurrentHashMap$KeyIterator.next(ConcurrentHashMap.java:1117)</i><br>
            </small><br>
            it fails here(ConcurrentHashMap implementation fragment):<br>
            <br>
            <small><i>final void advance() {<br>
                            if (nextEntry != null && (nextEntry
                = nextEntry.next) != null)<br>
                                return;<br>
                <br>
                            while (nextTableIndex >= 0) {<br>
                                if ( (nextEntry =
                currentTable[nextTableIndex--]) != null)<br>
                                    return;<br>
                            }<br>
                <br>
                            while (nextSegmentIndex >= 0) {<br>
                                Segment<K,V> seg =
                segments[nextSegmentIndex--];<br>
                                if (seg.count != 0) {<br>
                                    currentTable = seg.table;<br>
                                    for (int j = currentTable.length -
                1; j >= 0; --j) {<br>
                                        if ( (nextEntry =
                currentTable[j]) != null) {<b> <-- failure</b><br>
                                            nextTableIndex = j - 1;<br>
                                            return;<br>
                                        }<br>
                                    }<br>
                                }<br>
                            }<br>
                        }</i></small><br>
            <br>
            JVM info:<br>
            <br>
            <small><i>java version "1.6.0_30"<br>
                Java(TM) SE Runtime Environment (build 1.6.0_30-b12)<br>
                Java HotSpot(TM) Server VM (build 20.5-b03, mixed mode)</i></small><br>
          </div>
          <br>
          _______________________________________________<br>
          Concurrency-interest mailing list<br>
          <a href="mailto:Concurrency-interest@cs.oswego.edu" target="_blank">Concurrency-interest@cs.oswego.edu</a><br>
          <a href="http://cs.oswego.edu/mailman/listinfo/concurrency-interest" target="_blank">http://cs.oswego.edu/mailman/listinfo/concurrency-interest</a><br>
          <br>
        </blockquote>
      </div>
    </blockquote>
    <br>
  </div>

</blockquote></div>