诡异的HashMap
在JDK中,我们有很丰富的的已经写好的类库区使用,其中使用最多的就是集合类的,集合类中提供了Collection接口,List,Map等接口以及ArratList,LinkedList,HashMap等实现类。但是在并发中,我们并不能直接去使用这些实现类或者接口,因为这可能会造成一些问题,下面就是一个会造成问题的例子:
//并发下诡异的HashMap
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(new HashTest.AddThread(0));
Thread t2=new Thread(new HashTest.AddThread(1));
t1.start();
t2.start();
t1.join();
t2.join();
}
}
class HashTest{
static Map<String,String> map=new HashMap<String, String>();
public static class AddThread implements Runnable{
int start=0;
public AddThread(int start){
this.start=start;
}
public void run(){
for(int i=start;i<10000;i+=2){
map.put(Integer.toString(i),Integer.toBinaryString(i));
}
}
}
}
这段代码看似没有问题,但是实际上有很大的问题,由于多线程的冲突问题,Map中的链表成环了,所以上述的迭代就成了死循环。key1和key2互为对方的next元素。
谨慎尝试,CPU占用率很可能达100%,可能导致死机。
解决方案
JDK直接为我们解决了并发下容器类出现的问题,那就是JDK并发容器。他们大部分都存在java.util.concurrent这个包中。他们都有:
- ConcurrentHashMap
- CopyOnWriteArrayList
- ConcurrentLinkedQueue
- BlockingQueue
- ConcurrentSkipListMap
使用方法也很简单,除了以上方式,还可以使用其他方法,下面举一个HashMap的例子:
public static Map m= Collections.synchronizedMap(new HashMap());
而且,List等也可以使用类似的方式去使其在并发下不出现问题。
网友评论