来源:http://blog.youkuaiyun.com/yakihappy/article/details/3979292(加星)
如果需要使Map线程安全,大致有这么四种方法:
1、使用synchronized关键字,代码如下
synchronized(anObject) {
value=map.get(key);}
2、使用JDK1.5提供的锁(java.util.concurrent.locks.Lock)。代码如下
lock.lock();
value=map.get(key);
lock.unlock();
3、使用JDK1.5提供的读写锁(java.util.concurrent.locks.ReadWriteLock)。代码如下
rwlock.readLock().lock();
value=map.get(key);
rwlock.readLock().unlock();
这样两个读操作可以同时进行,理论上效率会比方法2高。
4、使用JDK1.5提供的java.util.concurrent.ConcurrentHashMap类。该类将Map的存储空间分为若干块,每块拥有自己的锁,大大减少了多个线程争夺同一个锁的情况。代码如下
value=map.get(key);//同步机制内置在get方法中
比较:
1、不同步确实最快,与预期一致。
2、四种同步方式中,ConcurrentHashMap是最快的,接近不同步的情况。
3、synchronized关键字非常慢,比使用锁慢了两个数量级。如果需自己实现同步,则使用JDK1.5提供的锁机制,避免使用synchronized关键字。
1.publicclassMapTest{
2.publicstaticfinalintTHREAD_COUNT=1;
3.publicstaticfinalintMAP_SIZE=1000;
4.publicstaticfinalintEXECUTION_MILLES=1000;
5.publicstaticfinalint[]KEYS=newint[100];
6.publicstaticvoidmain(String[]args)throwsException{
7.//初始化
8.Randomrand=newRandom();
9.for(inti=0;i<KEYS.length;++i)KEYS[i]=rand.nextInt();
10.//创建线程
11.longstart=System.currentTimeMillis();
12.Thread[]threads=newThread[THREAD_COUNT];
13.for(inti=0;i<THREAD_COUNT;++i){
14.threads[i]=newSynchronizedThread();
15.//threads[i]=newLockThread();
16.threads[i].start();
17.}
18.//等待其它线程执行若干时间
19.Thread.sleep(EXECUTION_MILLES);
20.//统计get操作的次数
21.longsum=0;
22.for(inti=0;i<THREAD_COUNT;++i){
23.sum+=threads[i].getClass().getDeclaredField("count").getLong(threads[i]); }
24.longmillisCost=System.currentTimeMillis()-start;
25.System.out.println(sum+"("+(millisCost)+"ms)");
26.System.exit(0);
27.}
28.
29.publicstaticvoidfillMap(Map<Integer,Integer>map){
30.Randomrand=newRandom();
31.for(inti=0;i<MAP_SIZE;++i){
32.map.put(rand.nextInt(),rand.nextInt());
33.}
34.}
35.}
36.classSynchronizedThreadextendsThread{
37.privatestaticMap<Integer,Integer>map=newHashMap<Integer,Integer>();
38.publiclongcount=0;
39.static{
40.MapTest.fillMap(map);
41.}
42.publicvoidrun(){
43.for(;;){
44.intindex=(int)(count%MapTest.KEYS.length);
45.synchronized(SynchronizedThread.class){
46.map.get(MapTest.KEYS[index]);
47.}
48.++count;
49.}
50.}
51.}
52.
53.classLockThreadextendsThread{
54.privatestaticMap<Integer,Integer>map=newHashMap<Integer,Integer>();
55.privatestaticLocklock=newReentrantLock();
56.publiclongcount=0;
57.static{
58.MapTest.fillMap(map);
59.}
60.publicvoidrun() {
61.for(;;){
62.intindex=(int)(count%MapTest.KEYS.length);
63.lock.lock();
64.map.get(MapTest.KEYS[index]);
65.lock.unlock();
66.++count;
67.}
68.}
69.}
70.