Tag: concurrenthashmap

具有零键function的线程安全映射

我需要一个multithreadingMap对象在我的Web服务器的缓存中使用,我需要null键。 HashMap允许我使用null键,但ConcurrentHashMap不允许。 我尝试使用Collections.synchronizedMap(new HashMap())创建HashMap的同步版本,但它也不接受null键。 有没有我可以使用的替代品,而不必实现某种方式来包装null键?

这段代码是线程安全的吗?

我想处理客户端请求流。 每个请求都有其特殊类型。 首先,我需要初始化该类型的一些数据,然后我可以开始处理请求。 当客户端类型第一次出现时,我只是初始化相应的数据。 在此之后,使用该数据处理该类型的所有以下请求。 我需要以线程安全的方式执行此操作。 这是我写的代码。 它是线程安全的吗? public class Test { private static Map clientTypesInitiated = new ConcurrentHashMap(); /* to process client request we need to create corresponding client type data. on the first signal we create that data, on the second – we process the request*/ void onClientRequestReceived(int clientTypeIndex) { if (clientTypesInitiated.put(clientTypeIndex, “”) […]

Java ConcurrentHashMap不是线程安全的..是吗?

之前我正在使用HashMap public Map clients = new HashMap(); 现在我已经切换到ConcurrentHashMap以避免同步块,现在我遇到了问题,我的服务器每秒都有大量加载200-400个并发客户端,预计会随着时间的推移而增长。 现在看起来像这样 public ConcurrentHashMap clients = new ConcurrentHashMap(); 我的服务器设计就像这样。 我有一个工作线程来处理大量的数据包。 每个数据包都使用packetHandler子程序(不是线程的一部分)进行检查,几乎任何客户端都可以在任何时候调用它,它几乎就像静态但不是。 我的整个服务器大多是单线程的,除了数据包处理部分。 无论如何,当有人使用命令时,如在线计算所有客户并从中获取一些信息。 客户端也可能会在计数正在进行时断开连接并从ConcurrentHashMap中删除(这会导致我的问题)。 另外我想在这里添加一些代码。 int txtGirls=0; int vidGirls=0; int txtBoys=0; int vidBoys=0; Iterator i = clients.values().iterator(); while (i.hasNext()) { UserProfile person = (UserProfile)i.next(); if(person != null) { if(person.getChatType()) { if(person.getGender().equals(“m”)) vidBoys++; else //<– crash occurs here. vidGirls++; […]

Oracle Java ConcurrentHashMap的错误实现?

我在Oracle的Java 8实现上测试ConcurrentHashMap : ConcurrentMap concurrentMap = new ConcurrentHashMap(); String result = concurrentMap.computeIfAbsent(“A”, k -> “B”); System.out.println(result); // “B” result = concurrentMap.putIfAbsent(“AA”, “BB”); System.out.println(result); // null computeIfAbsent的Javadoc确实这么说 实施要求: 默认实现等效于此映射的以下步骤,然后返回当前值,如果现在不存在则返回null: if (map.get(key) == null) { V newValue = mappingFunction.apply(key); if (newValue != null) return map.putIfAbsent(key, newValue); } 它表示然后返回当前值,如果现在不存在则返回null 。 那么它不应该返回null吗? 鉴于putIfAbsent也返回null 。 我在这里想念的是什么?

使用ConcurrentHashMap消除了数据可见性问题?

我已经阅读了Java Concurrency in Practice并留下了这个问题:当我使用ConcurrentHashMap时,本书第一部分讨论的数据并发问题我还需要担心吗? 以下是我的一个程序中的几个示例: 1.交易者的当前位置 (共享整数,其中’整数’是数学术语) 此数字表示trader对象当前拥有的内容并定义其状态。 它必须阅读它的位置,知道该做什么(寻找开始一个新的位置,或管理当前的位置)。 Trader方法在自己的线程上运行。 broker对象负责设定trader者的头寸。 每当交易者的一个订单被填满时,它将设置头寸。 Broker方法在自己的线程上运行。 trader和broker都在同一个包裹中。 Position作为包私有static ConcurrentHashMap 。 键是交易者对象的id。 值为Integer。 包的外部是应用程序。 它通过公共吸气剂间接获得交易者的头寸。 职位每隔几分钟最多会改变一次,因此broker不会经常触摸地图。 但是, trader和应用程序将经常阅读。 此外,我们经常有几个交易者同时阅读地图。 那么以这种方式使用ConcurrentHashMap,我不必处理锁定和数据可见性问题? ConcurrentHashMap可以处理所有事情吗? 2.市场(买入价,卖出价,最后价格) 几乎与位置相同的情况,除了现在broker将非常频繁地更新价格(在繁忙时间每秒最多10次更新;通常是每秒几次)。 trader和应用程序仍然经常读取。 现在,地图键是指示哪个库存或未来的代码,以及值是保持市场价格的对象。 它似乎工作正常,但在阅读JCIP后,我意识到如果事情没有正确实现,程序仍然可以被破坏。 这本书讨论了ConcurrentHashMap,但没有明确告诉我第一部分我们不再需要手动解决的问题。 在这种情况下, 似乎我不必synchronize任何东西。 那是对的吗?

最快的方法来初始化ConcurrentHashMap的值

ConcurrentHashMap通常在并发环境中用于在键下聚合某些事件 – 比如计算某些字符串值的命中。 如果我们事先不知道密钥,我们需要有一个很好的方法来初始化密钥的需要,它应该是快速和安全的并发性。 这个问题的最佳模式(就效率而言)是多少? 我将使用模型映射与声明如下: ConcurrentHashMap map = new ConcurrentHashMap(); 但它可能是一个包含任何键值对的映射,如果键中的键尚未存在,则需要初始化键值对,并将值状态变为记录事件。 有两种流行的方法:第一种使用ConcurrentHashMap.putIfAbsent : AtomicInteger count = map.get(s); if (count == null) { count = new AtomicInteger(0); AtomicInteger prevCount = map.putIfAbsent(s, count); if (prevCount != null) { count = prevCount; } } count.incrementAndGet(); 第二个使用ConcurrentHashMap.computeIfAbsent : AtomicInteger count = map.computeIfAbsent(s, (k) -> new AtomicInteger(0)); count.incrementAndGet(); 哪一个更适合这项任务? […]

使用常规HashMap双重检查锁定

回到并发。 到目前为止,很明显,对于double checked locking ,变量需要声明为volatile 。 但是,如果使用双重检查锁定,如下所示。 class Test { private final Map map = new HashMap(); public B fetch(A key, Function loader) { B value = map.get(key); if (value == null) { synchronized (this) { value = map.get(key); if (value == null) { value = loader.apply(key); map.put(key, value); } } } return value; } […]

Java并发:“级联”变量中的易失性与最终性?

是 final Map<Integer,Map> status = new ConcurrentHashMap<Integer, Map>(); Map<Integer,Map> statusInner = new ConcurrentHashMap<Integer, Map>(); status.put(key,statusInner); 同样的 volatile Map<Integer,Map> status = new ConcurrentHashMap<Integer, Map>(); Map<Integer,Map> statusInner = new ConcurrentHashMap<Integer, Map>(); status.put(key,statusInner); 如果内部Map由不同的线程访问? 或者甚至是这样的要求: volatile Map<Integer,Map> status = new ConcurrentHashMap<Integer, Map>(); volatile Map<Integer,Map> statusInner = new ConcurrentHashMap<Integer, Map>(); status.put(key,statusInner); 如果它不是“级联”映射,则final和volatile最终会产生相同的效果,即所有线程总是看到Map的正确内容……但是如果Map iteself包含一个map,会发生什么?如示例中所示…如何使内部地图正确“内存瘫痪”? 坦克! 汤姆

从理论上讲,ConcurrentHashMap的Segment和HashMap的桶之间有什么区别?

据我所知,在HashMap中,条目(Key,Value)基于散列(Key.hashCode)放置在桶中 – >表示桶位置的索引。 如果条目已经放置在该位置,则创建链接列表,并且新条目(如果它具有不同的键 – >通过equals()方法)放置在链接列表的开头。 我可以将这个概念与ConcurrentHashMap相关联,但是不是Buckets,而是有各个线程锁定的段。 而不是条目,有HashEntry(ies)。 以类似的方式,创建链接列表,如果插入的键值对不同,则基于键的equals(),它被放置在链表的末尾。 我说的是正确的:CHM的put是不同步的,因此任何线程都可以访问这个方法,这个put方法计算传递给它的密钥的哈希值并得到段索引(有点像桶)。 然后,仅针对该段,它调用put方法。 现在在Segment下,put方法指定会有一个lock(),这样只有一个线程可以改变特定段中的数据,从而得出结论,如果并发级别为16,则应该有16个线程,因此这些线程将是能够一次仅PUT值一个段。

并发hashMap putIfAbsent方法function

我是java世界的新bie并探索并发哈希映射,在探索并发hashmap API时,我发现了putifAbsent()方法 public V putIfAbsent(K paramK, V paramV) { if (paramV == null) throw new NullPointerException(); int i = hash(paramK.hashCode()); return segmentFor(i).put(paramK, i, paramV, true); } 现在请告知它的function是什么,我们什么时候需要它,如果可能的话请用一个简单的小例子来解释。