A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

传统容器的迭代器的并发问题
     一个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等并发库。注意,在并发环境下使用传统容器并对它进行修改,会出现异想不到的异常或错误。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马