package my.test;import java.util.HashMap;public class TestCircleHashMap {
private HashMap map = new HashMap();
private void putData(){
for(int i=0;i<100000;i++){
map.put(new Key(i), new Integer(i));
if(i%100 ==0){
System.out.println("put i="+i+" thread="+Thread.currentThread().getName());
}
reset();
}
System.out.println("put end thread="+Thread.currentThread().getName());
}// end putData

/**这个方法如果加上同步 private synchronized void reset(),仍然可能出现死循环,只是概率小一些,请不要关注这里
 * 重新指定hashmap。
 */
private synchronized void reset(){
if(map.size() > 1000){
map.clear();
map = new HashMap();
}
}//end reset

private class Key{
int v ;
private Key(int v){
this.v = v;
}
public int hashCode() {//返回相同的hash值
return 1;
}
public boolean equals(Object obj) {//由v值确定
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Key other = (Key) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (v != other.v)
return false;
return true;
}
private TestCircleHashMap getOuterType() {
return TestCircleHashMap.this;
}
}//end class

public static void main(String[] args) {
final TestCircleHashMap test = new TestCircleHashMap();
for(int i=0;i<2;i++){
new Thread("Thread_"+i){
public void run(){
test.putData();
}
}.start();
}
}
}

解决方案 »

  1.   

    map是两个线程共享的,当其中一个线程reset(){ 
    另一个还在map.put(new Key(i), new Integer(i)); 
    会出现问题,
      

  2.   


    import java.util.HashMap;public class TestCircleHashMap {
    private HashMap map = new HashMap(); @SuppressWarnings("unchecked")
    private void putData() {
    for (int i = 0; i < 100000; i++) {
    map.put(new Key(i), new Integer(i));
    if (i % 100 == 0) {
    System.out.println("put i=" + i + " thread="
    + Thread.currentThread().getName());
    }
    reset();
    }
    System.out
    .println("put end thread=" + Thread.currentThread().getName());
    }// end putData
    private synchronized void reset() {
    if (map.size() > 1000) {
    map.clear();
    //修改一:把下面这句注释掉了
    // map = new HashMap();
    }
    }// end reset private class Key {
    int v; private Key(int v) {
    this.v = v;
    } // 修改二:用eclipse自动生成的!!!!!!
    @Override
    public int hashCode() {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + v;
    return result;
    } @Override
    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    final Key other = (Key) obj;
    if (v != other.v)
    return false;
    return true;
    }
    }// end class @SuppressWarnings("unused")
    private TestCircleHashMap getOuterType() {
    return TestCircleHashMap.this;
    } public static void main(String[] args) {
    final TestCircleHashMap test = new TestCircleHashMap();
    for (int i = 0; i < 2; i++) {
    new Thread("Thread_" + i) {
    public void run() {
    test.putData();
    }
    }.start();
    }
    }
    }lz再测试看看......
      

  3.   

    是hashmap扩容时因线程不安全产生死循环
    楼主有兴趣可以参看HashMap的源代码
      

  4.   


    同意,如果把put方法同步一下的话就不会出现死锁的问题