先了解下ThreadLocal
ThreadLocal<String> tl = new ThreadLocal<>();
多线程情况下,共享数据,为每一个线程保存变量。
ThreadLocal就是一个Map,Key --> Thread.getCurrentThread() Value --> 线程需要保存的变量。
ThreadLocal.set("value") --> Map.put(Thread.getCurrentThread(), "value")
内存问题
在并发量高的时候,可能内存溢出。使用的时候,在线程结束之前一定要释放当前线程保存的变量。这是因为线程销毁,并不会影响容器中的变量,所以要调用ThreadLocal的remove方法删除,并且并发情况下,操作系统为了提高效率,不一定会马上销毁线程,而是把线程的引用数据置空,此时再用此线程去操作,而容器为清空,会导致获取到之前处理到的数据。
同步容器
解决并发情况下的容器安全问题。我们最先接触的线程安全容器Vector、HashTable都是基于底层Synchronized来实现。而concurrent包下的线程安全容器大多数是使用系统底层来实现的,类似native。java8中使用CAS.
Map/Set
ConcurrentHashMap/ConcurrentSet
底层哈希实现的同步Map(Set)。效率高,线程安全。使用系统底层实现,量级较synchronized轻。
代码(上) 代码(下) hashtable的执行时间 concurrentHashMap执行时间对比相差不大,可以增加put的数量,同时扩大map的key(因为key的可选值越少,hash值比对越少,key是通过hash来查找的)
增加添加数据 hashtable 的执行时间 concurrentHashMap执行时间ConcurrentSkipListMap/ConcurrentSkipListSet
底层跳表(skipList)实现的同步(Map/Set)。有序,效率比ConcurrentHashMap稍低。同数据量插入,比hashTable低。但是hashTable不推荐使用了。
CopyOnWriteArrayList 读取效率高,写效率低。写的效率低是因为,每次写数据,都会复制一份新的数组,在新数组上进行新增,这样新增三个数据,就会存在三份空间。
Queue
ConcurrentLinkedQueue
代码 运行结果队列--链表实现FIFO(先进先出)
网友评论