当前位置:嗨网首页>书籍在线阅读

25-结果分析

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

结果分析

在本节中,我们成功利用 ConcurrentHashMap 来存储由user创建的operation信息。更进一步来说,散列表以 Operation 类的user字段作为一个key,并以 Concurrent LinkedDeque 作为value,基于此来存储所有与user相关联的operation。

首先,要用10个不同线程来将随机数据填充到散列中。为达此目的,要实现一个 HashFiller 的任务。但最大的问题就是在插入一个key到散列表的时候所发生的意外:如果两个线程同时插入同一个key的时候,则将会丢失其中一个线程插入的数据,并且还会出现数据竞争的情况。为了解决该类问题,就要使用 computeIfAbsent() 方法。

该方法接收一个key和一个实现 Function 接口的lambda表达式,它们会以参数的形式进行传递。如果key已经存在,则该方法会返回与key相对应的value。否则,它会执行指定的 Function 对象,还会通过 Function 把key和value返回到 HashMap 中。在本例中,由于key不存在,所以就创建了一个新的 ConcurrentLinkedDeque 类型的实例。该方法的主要优势是其执行操作是原子性的,因此,如果其他线程尝试执行相同的操作,则它就会发生阻塞直到占用该方法的操作执行完为止。

而且,在 main() 方法中还使用了 ConcurrentHashMap 的其他方法来处理存储在散列中的信息。

  • forEach() :该方法接收一个实现 BiConsumer 接口的lambda表达式作为参数。而该lambda表达式的另外两个参数就是正在使用的元素的key和value。该方法的lambda表达式的作用是存储所有的元素在 ConcurrentHashMap 中。
  • forEachEntry() :该方法与上一个相同,但其lambda表达式实现的是 Consumer 接口。它接收一个存储了key和value的 Entry 对象作为参数。这就是执行相同功能的另一种方式。
  • search() :该方法接收一个实现 BiFunction 接口的lambda表达式作为参数。该lambda表达式同样也是以 ConcurrentHashMap 中entry的key和value作为参数。它通过 BiFunction 来返回第一个非空值。
  • reduce() :该方法接收两个 BiFunction 接口来处理 ConcurrentHashMap 的元素,并聚合为一个唯一值。这可以实现一个基于 ConcurrentHashMap 元素的 MapReduce 操作。第一个 BiFunction 接口可以转换元素的key和value成为一个唯一值,而第二个 BiFunction 接口可以聚合两个不同元素的值。

所有方法都声明第一个参数名为 parallelismThreshold 。它是执行一个元素数量(近似)的操作所需的并发量。也就是说,如果 ConcurrentHashMap 用比元素数量更少的值作为参数,则该方法将会以串行方式来执行。相反(在本案例中),该方法是以并行方式来执行的。