黑马程序员:Java培训、Android培训、iOS培训、.Net培训

      JAVA集合-迭代器的并发问题

传统容器的迭代器的并发问题

     一个HashMap的案例:造成死循环

      下面是HashMap的get方法的代码:

          public V get(Object key){

              if(key == null) return getForNullKey();

              int hash = hash(key.hashCode());

              for(Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next()){

                  Object k;

                  if(e.hash == hash && ((k = e.key) == key || key.equals(k)))

                      return e.value;

              }

              return null;

          }

      原因:get方法会根据key的hashCode来锁定多个对象,并且遍历这些对象来找到key所对应的对象。当多个线程不安全的修改HashMap数据结构的时候,有可能使得这个方法进入死循环。

      死循环举例:

          count = 4;

          while(hasnext()){next();}  A

          next(){cursor++;}

          hasnext(){

               if(cursor == count) return false;  B

               return ture;

          }

          线程TA:在A处执行4次next()完成的那刹那,TA阻塞,此时,cursor=4

          线程TB:在A处执行next(),使得cursor=5,可见,永远不会出现B处cursor == count的情况。因此,程序进入死循环。

      历史教训:在并发环境下,应当使用ConcurrentHashMap等并发库。注意,在并发环境下使用传统容器并对它进行修改,会出现异想不到的异常或错误。