zoukankan      html  css  js  c++  java
  • 006-多线程-集合-Set-ConcurrentSkipListSet

    一、简介

     ConcurrentSkipListSet是线程安全的有序的集合,适用于高并发的场景。
    ConcurrentSkipListSet和TreeSet,它们虽然都是有序的集合。但是,第一,它们的线程安全机制不同,TreeSet是非线程安全的,而ConcurrentSkipListSet是线程安全的。第二,ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的,而TreeSet是通过TreeMap实现的。

    1.1、原理和数据结构

     

      说明
    (01) ConcurrentSkipListSet继承于AbstractSet。因此,它本质上是一个集合。
    (02) ConcurrentSkipListSet实现了NavigableSet接口。因此,ConcurrentSkipListSet是一个有序的集合。
    (03) ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的。它包含一个ConcurrentNavigableMap对象m,而m对象实际上是ConcurrentNavigableMap的实现类ConcurrentSkipListMap的实例。ConcurrentSkipListMap中的元素是key-value键值对;而ConcurrentSkipListSet是集合,它只用到了ConcurrentSkipListMap中的key!

    1.2、示例

    /*
     *   ConcurrentSkipListSet是“线程安全”的集合,而TreeSet是非线程安全的。
     *
     *   下面是“多个线程同时操作并且遍历集合set”的示例
     *   (01) 当set是ConcurrentSkipListSet对象时,程序能正常运行。
     *   (02) 当set是TreeSet对象时,程序会产生ConcurrentModificationException异常。
     *
     */
    public class ConcurrentSkipListSetDemo1 {
    
        // TODO: set是TreeSet对象时,程序会出错。
        //private static Set<String> set = new TreeSet<String>();
        private static Set<String> set = new ConcurrentSkipListSet<String>();
    
        public static void main(String[] args) {
    
            // 同时启动两个线程对set进行操作!
            new MyThread("a").start();
            new MyThread("b").start();
        }
    
        private static void printAll() {
            String value = null;
            Iterator iter = set.iterator();
            while (iter.hasNext()) {
                value = (String) iter.next();
                System.out.print(value + ", ");
            }
            System.out.println();
        }
    
        private static class MyThread extends Thread {
            MyThread(String name) {
                super(name);
            }
    
            @Override
            public void run() {
                int i = 0;
                while (i++ < 10) {
                    // “线程名” + "序号"
                    String val = Thread.currentThread().getName() + (i % 6);
                    set.add(val);
                    // 通过“Iterator”遍历set。
                    printAll();
                }
            }
        }
    }

    1.3、使用场景

    二、源码分析

  • 相关阅读:
    mysql 查询技巧
    如何查看mysql索引
    windows下安装redis以及简单的事例
    Buildroot make网卡interfaces文件被修改
    VirtualBox只能生成32位虚拟机
    python-websocket-server hacking
    crontab定时任务
    Linux修改串口irq
    emmc boot_config文件不存在
    /dev/mem直接操作硬件寄存器
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11068571.html
Copyright © 2011-2022 走看看