Java中的同步hashmap只读访问

时间:2013-04-01 20:25:15

标签: java multithreading hashmap synchronized readonly

在Java中,有3个线程想要访问(只读)不可变的hashmap来执行某些操作。对于那个目的,SynchronizedMap类是否是最快的解决方案?如果没有,那么什么会更快使用?

import com.carrotsearch.hppc.IntObjectMap;
import com.carrotsearch.hppc.IntObjectOpenHashMap;

public class abc {
    public static void main(String[] args) {

        final IntObjectMap<int[]> map = new IntObjectOpenHashMap<int[]>();
        for (int i = 0; i < 4; i++) {
            map.put(i, new int[] {1, 2, 3, 4, 5});
        }

        Thread[] threads = new Thread[3];

        class SynchronizedMap {

            private final Object syncObject = new Object();

            public final int[] read(int i) {

                final int[] value;

                synchronized (syncObject) {

                    // code that reads-only immutable map object
                    value = map.get(i);

                }

                return value;

            }
        }

        final SynchronizedMap syncMap = new SynchronizedMap();

        class AccessMap implements Runnable {

            private int id;
            AccessMap(int index) { id = index; }

            public void run() {

                // code that reads-only immutable map object like this:
                for (int i = 0; i < 4; i++) {

                    final int[] array = syncMap.read(i);

                    for (int j = 0; j < array.length; j++)
                        System.out.println(id + ": " + array[j] + " ");

                }

            }
        }

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new AccessMap(i) {});
            threads[i].start();
        }

        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

1 个答案:

答案 0 :(得分:4)

  

SynchronizedMap类是否是为此目的最快的解决方案?

没有。如果HashMap是真正的不可变/只读,那么volatile Map<...>就是可行的方法。

volatile IntObjectMap<int[]> readOnlyMap = new IntObjectOpenHashMap<int[]>();

如果您在之后启动线程,那么您甚至不需要volatile。您需要volatile的唯一时间是您正在交换当前正在运行的线程正在访问的新地图。

final IntObjectMap<int[]> readOnlyMap = new IntObjectOpenHashMap<int[]>();