java并发编程第六章(6)使用线程安全可遍历映射

5.使用线程安全可遍历映射
本范例用到的接口和实现类:ConcurrentNavigableMap接口及其实现类。实现这个接口的类以如下两部分存放元素
1.一个键值(key),它是元素的标示并且是唯一的。
2.元素其他部分数据。

 ConcurrentSkipListMap类实现了ConcurrentNavigaleMap接口。从内部实现机制来讲,它使用了一个Skip List来存放数据。
 Skip List是基于并发列表的数据结构,效率与二叉树相近。通过该类就可以得到一个数据结构,比有序列表在添加,搜索,或者删除元素耗费更少的
 访问时间。
  当你插入元素到映射中时,ConcurrentSkipListMap接口类使用键值阿里排序所有元素,除了提供返回一个具体元素的方法之外,这个类也提供获取子映射的方法 。
   ConccurentNavigableMap<String,Contact> submap = map.submap(String from ,String to );
使用方法:
firstEntry():返回一个Map.Entry对象,含有映射中的第一个元素。这个方法不会从映射中移除元素。Map.Entry对象包含键值和元素。使用getValue()方法就能获取元素,
使用getKey()方法就能够获取元素的键值。
headMap(K toKey):K是在ConcurrentSkipListMap对象的泛型参数里用到的键。这个方法返回映射中所有键值小于参数值toKey的子映射。
tailMap(K fromKey):K是在ConcurrentSkipListMap对象的泛型参数里用到的键,返回映射中所有键值待遇参数值fromKey的子映射。
putIfAbsent(K key,V value): 如果映射中不存在键key,那么就将Key和value保存到映射中。
polllLastEntry():返回并移除映射中的最后一个Map.Entry()对象。
replace(K key , V value):如果映射中已经存在键Key,则用参数中的value替换现有的值。
实例代码:
public class Contact {
    private String name;
    private String phone;
    public Contact(String name, String phone) {
        super();
        this.name = name;
        this.phone = phone;
    }
    public String getName() {
        return name;
    }
    public String getPhone() {
        return phone;
    }

}
/**
 * 
 * @author fcs
 * @date 2015-6-21
 * 描述:使用线程安全可遍历映射
 * 说明:
 */
public class Task  implements Runnable{
    private ConcurrentSkipListMap<String,Contact> map;
    private String id;

    public Task(ConcurrentSkipListMap<String, Contact> map, String id) {
        this.map = map;
        this.id = id;
    }

    @Override
    public void run() {
        for(int i = 0;i< 1000;i++){
            Contact contact = new Contact(id,String.valueOf(i+1000));
            //这里如果插入的键值已经存在,就用新插入的值覆盖已有的值
            map.put(id+contact.getPhone(), contact);
        }
    }

}
public class Main {
    public static void main(String[] args) {
        ConcurrentSkipListMap<String,Contact>  map = new ConcurrentSkipListMap<String, Contact>();
        Thread threads []= new Thread[25];
        int counter = 0;
        for(char i = 'A';i<'Z';i++){
            Task task = new Task(map,String.valueOf(i));
            threads[counter] = new Thread(task);
            threads[counter].start();
            counter++;
        }

        //使用join()方法等待所有线程执行完成。

        for(int i = 0;i< 25;i++){
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.printf("Main: Size of the map: %d\n",map.size());
        Map.Entry<String, Contact> element;   //map.entry是map接口的一个内部接口,它的作用就是包装一个map的节点,这个节点
        //封装了key,value以及别的值(比如hashmap中的哈希码和next指针)
        Contact contact;
        //使用firstEntry()方法获取map中的第一个元素
        element = map.firstEntry();  
        contact = element.getValue();
        System.out.printf("Main: First Entry: %s: %s\n",contact.getName(),contact.getPhone());

        //使用lastEntry()方法获取map中的最后一个元素
        element = map.lastEntry();
        contact = element.getValue();
        System.out.printf("Main: Last Entry: %s %s\n",contact.getName(),contact.getPhone());

        //使用subMap()取得map的一个子映射,将这些数据输出到控制台。
        System.out.println("Main: Submap from A1996 to B1002 :");

        //该方法返回含有映射部分元素的ConcurrentNavigableMap对象。
        ConcurrentNavigableMap<String, Contact> submap = map.subMap("A1996", "B1002");
        do{
            element = submap.pollFirstEntry();
            if(element!=null){
                contact = element.getValue();
                System.out.printf("%s: %s\n",contact.getName(),contact.getPhone());
            }
        }while(element != null);
    }
}

运行结果:
运行截图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值