map读写操作是线程安全吗

 我来答
huanglenzhi
2015-02-09 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517183
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  需要使 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 关键字。

  

  public class MapTest {
  public static final int THREAD_COUNT = 1;
  public static final int MAP_SIZE = 1000;
  public static final int EXECUTION_MILLES = 1000;
  public static final int[] KEYS = new int[100];

  public static void main(String[] args) throws Exception {
  // 初始化
  Random rand = new Random();
  for (int i = 0; i < KEYS.length; ++i)
  KEYS[i] = rand.nextInt();
  // 创建线程
  long start = System.currentTimeMillis();
  Thread[] threads = new Thread[THREAD_COUNT];
  for (int i = 0; i < THREAD_COUNT; ++i) {
  threads[i] = new SynchronizedThread();
  // threads[i] = new LockThread();
  threads[i].start();
  }
  // 等待其它线程执行若干时间
  Thread.sleep(EXECUTION_MILLES);
  // 统计 get 操作的次数
  long sum = 0;
  for (int i = 0; i < THREAD_COUNT; ++i) {
  sum += threads[i].getClass().getDeclaredField("count")
  .getLong(threads[i]);
  }
  long millisCost = System.currentTimeMillis() - start;
  System.out.println(sum + "(" + (millisCost) + "ms)");
  System.exit(0);
  }

  public static void fillMap(Map<Integer, Integer> map) {
  Random rand = new Random();
  for (int i = 0; i < MAP_SIZE; ++i) {
  map.put(rand.nextInt(), rand.nextInt());
  }
  }
  }
  class SynchronizedThread extends Thread {
  private static Map<Integer, Integer> map = new HashMap<Integer, Integer>();
  public long count = 0;
  static {
  MapTest.fillMap(map);
  }

  public void run() {
  for (;;) {
  int index = (int) (count % MapTest.KEYS.length);
  synchronized (SynchronizedThread.class) {
  map.get(MapTest.KEYS[index]);
  }
  ++count;
  }
  }
  }

  class LockThread extends Thread {
  private static Map<Integer, Integer> map = new HashMap<Integer, Integer>();
  private static Lock lock = new ReentrantLock();
  public long count = 0;
  static {
  MapTest.fillMap(map);
  }

  public void run() {
  for (;;) {
  int index = (int) (count % MapTest.KEYS.length);
  lock.lock();
  map.get(MapTest.KEYS[index]);
  lock.unlock();
  ++count;
  }
  }
  }
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式