ConcurrentNavigableMap

本文详细介绍了Java中的ConcurrentNavigableMap接口,重点讲解了其并发访问特性,以及`headMap()`、`tailMap()`和`subMap()`等方法的使用,并提到了`descendingKeySet()`、`descendingMap()`和`navigableKeySet()`等其他有用的方法。

本文翻译自http://tutorials.jenkov.com/java-util-concurrent/concurrentnavigablemap.html,人工翻译,仅供学习交流。

ConcurrentNavigableMap

ConcurrentNavigableMap类是为了支持NavigableMap并发访问的而设计的子接口,使其子类可以实现并发访问。可以通过不同的方法,如 headMap(), subMap() 和tailMap(),返回这些子类。
比起重新解释NavigableMap中的所有方法,我只会关注在ConcurrentNavigableMap增加的方法(译者注:jdk1.8中ConcurrentNavigableMap所有的方法均重写NavigableMap)。

headMap()

headMap(T toKey)方法会返回一个key值小于给定的值的一个map集合。
如果改变初始集合,这个改动也会映射到headMap中。
下面是使用headMap()方法的的示例:

ConcurrentNavigableMap map = new ConcurrentSkipListMap();

map.put("1", "one");
map.put("2", "two");
map.put("3", "three");

ConcurrentNavigableMap headMap = map.headMap("2");

headMap将指向一个ConcurrentNavigableMap,它只包含键"1",因为只有这个键严格小于“2”。
有关该方法如何工作的更多具体细节,以及重载版本是如何工作的,请参阅JavaDoc。

tailMap()

tailMap(T fromKey) 方法返回一个key值大于和等于给定的值的一个map集合。
如果改变初始集合,这个改动也会映射到tailMap中。
下面是使用tailMap()方法的的示例:

ConcurrentNavigableMap map = new ConcurrentSkipListMap();

map.put("1", "one");
map.put("2", "two");
map.put("3", "three");

ConcurrentNavigableMap tailMap = map.tailMap("2");

tailMap包含key值“2”和“3”,因为这两个键大于或等于“2”。
有关该方法如何工作的更多具体细节,以及重载版本是如何工作的,请参阅JavaDoc。

subMap()

subMap(K fromKey, K toKey)方法返回一个参数中从fromKey(包含)到tokey(不包含)的部分集合。下面有个示例:

ConcurrentNavigableMap map = new ConcurrentSkipListMap();

map.put("1", "one");
map.put("2", "two");
map.put("3", "three");

ConcurrentNavigableMap subMap = map.subMap("2", "3");

返回的子map只包含键“2”,因为只有这个键大于或等于“2”。

更多方法

ConcurrentNavigableMap接口还包含一些可能有用的方法。例如:

  • descendingKeySet()
  • descendingMap()
  • navigableKeySet()
    有关这些方法的更多信息,请参阅官方JavaDoc。
下一节: CountDownLatch
// 异步批量发布确认模式 public static void publishMessageAsync() throws Exception { Channel channel = RabbitMqUtils.getChannel(); channel.queueDeclare(QUEUE_NAME_ASYNC, true, false, false, null); // 开启发布确认 channel.confirmSelect(); /** * 线程安全有序的一个哈希表(map) 适用于高并发的情况下 * 1.轻松的将序号与消息进行关联 * 2.轻松的批量删除条目 只要给到序号 * 3.支持高并发(多线程) */ ConcurrentSkipListMap<Long, String> outstandingConfirms = new ConcurrentSkipListMap<>(); /** * // 消息确认成功 回调函数 * 1. deliveryTag 消息的标识 * 2. multiple 是否为批量确认 */ ConfirmCallback ackCallback = (deliveryTag, multiple) -> { //TODO 2.删除掉已经确认的消息 判断是批量的就一起清理 单个的就直接删除 if (multiple) { ConcurrentNavigableMap<Long, String> confirmed = outstandingConfirms.headMap(deliveryTag); confirmed.clear(); }else { outstandingConfirms.remove(deliveryTag); } System.out.println("确认的消息: " + deliveryTag); }; /** * // 消息确认失败 回调函数 * 1. deliveryTag 消息的标识 * 2. multiple 是否为批量确认 */ ConfirmCallback nackCallback = (deliveryTag, multiple) -> { //TODO 3. 打印一下未确认的消息都有哪些 String message = outstandingConfirms.get(deliveryTag); System.out.println("未确认的消息是: " + message + "------------未确认消息的tag是: " + deliveryTag); }; /** * 准备消息的监听器 监听哪些消息成功了 哪些消息失败了 * 1. 监听哪些消息成功了 * 2. 监听哪些消息失败了 */ channel.addConfirmListener(ackCallback, nackCallback); // 异步通知 // 记录开始时间 long begin = System.currentTimeMillis(); // 批量发送消息 for (int i = 0; i < MESSAGE_COUNT; i++) { String message = "消息" + i; channel.basicPublish("", QUEUE_NAME_ASYNC, null, message.getBytes()); //TODO 1.此处记录下所有要发送的消息 消息的总和 outstandingConfirms.put(channel.getNextPublishSeqNo(), message); } // 记录结束时间 long end = System.currentTimeMillis(); System.out.println("发布" + MESSAGE_COUNT + "条异步批量确认消息, 耗时" + (end - begin) + "ms"); }
最新发布
04-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值