亲宝软件园·资讯

展开

Java ConcurrentHashMap线程安全 Java中ConcurrentHashMap是怎样实现线程安全

海拥 人气:0
想了解Java中ConcurrentHashMap是怎样实现线程安全的相关内容吗,海拥在本文为您仔细讲解Java ConcurrentHashMap线程安全的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Java,ConcurrentHashMap线程安全,ConcurrentHashMap线程安全,下面大家一起来学习吧。

ConcurrentHashMap是一个哈希表,支持检索的全并发和更新的高预期并发。此类遵循与 Hashtable 相同的功能规范,并包含 Hashtable 的所有方法。ConcurrentHashMap 位于 java.util.Concurrent 包中。

语法:

public class ConcurrentHashMap<K,V>
extends AbstractMap<K,V>
implements ConcurrentMap<K,V>, Serializable

其中 K 指的是这个映射所维护的键的类型,V 指的是映射值的类型

ConcurrentHashmap 的需要:

如何使 ConcurrentHashMap 线程安全成为可能?

示例 1:

import java.util.*;
import java.util.concurrent.*;

// 扩展Thread类的主类
class GFG extends Thread {

 // 创建静态 HashMap 类对象
 static HashMap m = new HashMap();

 public void run()
 {

  // try 块检查异常
  try {

   // 让线程休眠 3 秒
   Thread.sleep(2000);
  }
  catch (InterruptedException e) {
  }
  System.out.println("子线程更新映射");
  m.put(103, "C");
 }
 public static void main(String arg[])
  throws InterruptedException
 {
  m.put(101, "A");
  m.put(102, "B");
  GFG t = new GFG();
  t.start();
  Set s1 = m.keySet();
  Iterator itr = s1.iterator();
  while (itr.hasNext()) {
   Integer I1 = (Integer)itr.next();
   System.out.println(
    "主线程迭代映射和当前条目是:"
    + I1 + "..." + m.get(I1));
   Thread.sleep(3000);
  }
  System.out.println(m);
 }
}

输出:
主线程迭代映射和当前条目是:101...A
子线程更新映射
Exception in thread "main" java.util.ConcurrentModificationException
       at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
       at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1516)
       at Main.main(Main.java:30)

输出说明:

上述程序中使用的类扩展了 Thread 类。让我们看看控制流。所以,最初,上面的java程序包含一个线程。当我们遇到语句 Main t= new Main() 时,我们正在为扩展 Thread 类的类创建一个对象。因此,每当我们调用 t.start() 方法时,子线程都会被激活并调用 run() 方法. 现在主线程开始执行,每当子线程更新同一个地图对象时,都会抛出一个名为 ConcurrentModificationException 的异常。    

现在让我们使用 ConcurrentHashMap 来修改上面的程序,以解决上述程序在执行时产生的异常。

示例 2:

import java.util.*;
import java.util.concurrent.*;

class Main extends Thread {
 static ConcurrentHashMap<Integer, String> m
  = new ConcurrentHashMap<Integer, String>();
 public void run()
 {
  try {
   Thread.sleep(2000);
  }
  catch (InterruptedException e) {
  }
  System.out.println("子线程更新映射");
  m.put(103, "C");
 }
 public static void main(String arg[])
  throws InterruptedException
 {
  m.put(101, "A");
  m.put(102, "B");
  Main t = new Main();
  t.start();
  Set<Integer> s1 = m.keySet();
  Iterator<Integer> itr = s1.iterator();
  while (itr.hasNext()) {
   Integer I1 = itr.next();
   System.out.println(
    "主线程迭代映射和当前条目是:"
    + I1 + "..." + m.get(I1));
   Thread.sleep(3000);
  }
  System.out.println(m);
 }
}

输出

主线程迭代映射和当前条目是:101...A
子线程更新映射
主线程迭代映射和当前条目是:102...B
主线程迭代映射和当前条目是:103...C
{101=A, 102=B, 103=C}

输出说明:
上述程序中使用的 Class 扩展了Thread 类。让我们看看控制流,所以我们知道在 ConcurrentHashMap 中,当一个线程正在迭代时,剩余的线程可以以安全的方式执行任何修改。上述程序中主线程正在更新Map,同时子线程也在尝试更新Map对象。本程序不会抛出 ConcurrentModificationException。

Hashtable、Hashmap、ConcurrentHashmap的区别

Hashtable Hashmap ConcurrentHashmap
我们将通过锁定整个地图对象来获得线程安全。 它不是线程安全的。 我们将获得线程安全,而无需使用段级锁锁定 Total Map 对象。
每个读写操作都需要一个objectstotal 映射对象锁。 它不需要锁。 读操作可以不加锁执行,写操作可以用段级锁执行。
一次只允许一个线程在地图上操作(同步) 不允许同时运行多个线程。它会抛出异常 一次允许多个线程以安全的方式操作地图对象
当一个线程迭代 Map 对象时,其他线程不允许修改映射,否则我们会得到 ConcurrentModificationException 当一个线程迭代 Map 对象时,其他线程不允许修改映射,否则我们会得到 ConcurrentModificationException 当一个线程迭代 Map 对象时,其他线程被允许修改地图,我们不会得到 ConcurrentModificationException
键和值都不允许为 Null HashMap 允许一个空键和多个空值 键和值都不允许为 Null。
在 1.0 版本中引入 在 1.2 版本中引入 在 1.5 版本中引入

加载全部内容

相关教程
猜你喜欢
用户评论