同步容器简介

针对容器我们知道有HashMap,HashTable,其中HashMap是一个非线程安全的,HashMap在并发执行put操作时会引起死循环,导致CPU利用率接近100%。因为多线程会导致HashMap的Node链表形成环形数据结构,一旦形成环形数据结构,Node的next节点永远不为空,就会在获取Node时产生死循环,而且死循环发生在发生在扩容时

HashTable是线程安全的,但是在复合操作上会线程不安全的现象。

备注:

1)什么是复合操作?比如添加元素,需先判断是否元素存在,元素不存在时才添加。

2)hashtable是在插入和删除上都是索表的方式,因此效率特别低。

在jdk1.5之后提供java.util.concurrent包下的一些同步容器:java.util.concurrent.ConcurrentHashMap<K, V>。

ConcurrentHashMap性能讲解:

ConcurrentHashMap的性能要比HashTable性能高,而且高很多。

1)ConcurrentHashMap在jdk1.7之前采用了“锁分段”机制,默认把一个ConcurrentHashMap分为16个segment,每个segment下默认也是长度为16的哈希表,在每个哈希元素下是链表。这样就可默认每段有一个锁,一次可以最大并发操作16。

2)在jdk1.8之后ConcurrentHashMap采用CAS算法,可以把CAS算法错略的认为是无锁算法。

3)java.util.concurrent包还提供了设计用于多线程上下文中的Collection实现:ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList和CopyOnWriteArraySet。

4)当希望许多线程访问一个给定的Collection时

  a)ConcurrentHashMap由于同步的HashMap;

  b)ConcurrentSkipListMap通常优于同步的TreeMap;

5)当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList优于同步的ArrayList。

CopyOnWriteArrayList的用法示例:

测试ArrayList并发读写:

  1. package com.dx.juc.test;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.List;
  6.  
  7. public class CopyOnWriteTest {
  8. public static void main(String[] args) {
  9. new Thread(new MyCopyOnWrite()).start();
  10. }
  11. }
  12.  
  13. class MyCopyOnWrite implements Runnable {
  14. private static List<String> items = Collections.synchronizedList(new ArrayList<String>());
  15.  
  16. static {
  17. items.add("A");
  18. items.add("B");
  19. items.add("C");
  20. }
  21.  
  22. public void run() {
  23. for (String item : items) {
  24. System.out.println(item);
  25. items.add("D");
  26. }
  27. }
  28.  
  29. }

在执行时,抛出异常:

  1. A
  2. Exception in thread "Thread-0" java.util.ConcurrentModificationException
  3. at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
  4. at java.util.ArrayList$Itr.next(ArrayList.java:831)
  5. at com.dx.juc.test.MyCopyOnWrite.run(CopyOnWriteTest.java:23)
  6. at java.lang.Thread.run(Thread.java:745)

如果使用CopyOnWriteArrayList时,并不会抛出异常,原理是每次在写入时,会在底层拷贝一份新的数据,因此如果是写入时性能不高。

  1. package com.dx.juc.test;
  2.  
  3. import java.util.Iterator;
  4. import java.util.concurrent.CopyOnWriteArrayList;
  5.  
  6. public class CopyOnWriteTest {
  7. public static void main(String[] args) {
  8. MyCopyOnWrite myCopyOnWrite = new MyCopyOnWrite();
  9.  
  10. for (int i = 0; i < 5; i++) {
  11. new Thread(myCopyOnWrite).start();
  12. }
  13. }
  14. }
  15.  
  16. class MyCopyOnWrite implements Runnable {
  17. private static CopyOnWriteArrayList<String> items = new CopyOnWriteArrayList<String>();
  18.  
  19. static {
  20. items.add("A");
  21. items.add("B");
  22. items.add("C");
  23. }
  24.  
  25. public void run() {
  26. System.out.println(Thread.currentThread().getName() + ":start");
  27. Iterator<String> iterator = items.iterator();
  28. while (iterator.hasNext()) {
  29. System.out.println(Thread.currentThread().getName() + ":" + iterator.next());
  30. items.add("D");
  31. }
  32. System.out.println(Thread.currentThread().getName() + ":end");
  33. }
  34.  
  35. }

Java-JUC(四):同步容器介绍的更多相关文章

  1. java多线程总结-同步容器与并发容器的对比与介绍

    1 容器集简单介绍 java.util包下面的容器集主要有两种,一种是Collection接口下面的List和Set,一种是Map, 大致结构如下: Collection List LinkedLis ...

  2. java并发:同步容器&并发容器

    第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...

  3. Java线程安全同步容器

    线程安全同步容器(使用 synchronized关键字) 1.ArrayList->Vector,Stack 2.HashMap->HashTable(key.value不能为null) ...

  4. java 并发 (四) ---- 并发容器

    Hashmap 和 Concurrenthashmap Hashmap 不适合并发,应该使用ConcurrentHashMap . 这是很多人都知道的,但是为什么呢? 可以先看一下这两篇文章. JDK ...

  5. Java并发编程--同步容器

    BlockingQueue 阻塞队列 对于阻塞队列,如果BlockingQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤 ...

  6. 【转】Java并发编程:同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch).今天我们就来讨论下同步容器. ...

  7. 【Java并发编程二】同步容器和并发容器

    一.同步容器 在Java中,同步容器包括两个部分,一个是vector和HashTable,查看vector.HashTable的实现代码,可以看到这些容器实现线程安全的方式就是将它们的状态封装起来,并 ...

  8. Java并发—同步容器和并发容器

    简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同步的容器,比如Vector.Ha ...

  9. Java并发编程:同步容器

    Java并发编程:同步容器 为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch). ...

随机推荐

  1. shell 常用命令语句

    查找并删除 sudo fing / -name '*fcitx*' | xargs sudo rm -rf find . -type d -name ‘.svn’ | xargs rm -rf fin ...

  2. windows下用nginx配置https服务器

    1.安装nginx 先到nginx官网下在nginx http://nginx.org/en/download.html 将下载好的文件解压出来修改文件名为 nginx ,然后拷贝到C盘下,目录如下: ...

  3. 什么是NAS

    个人理解: 1.NAS本身不是一种传输协议,只是一个名词而已,就是一个网络储存. 2.NAS系统本身就是一个Linux,也不是什么发行版,就是在Linux下实现了网络储存. 3.NAS系统里面实现了很 ...

  4. bitnami redmine配置全过程

    常见问题: 我在自己的机器上面配置完毕以后,移植到另外一台机器上面,登陆页面总是在检查network,并且最后网络加载失败,不论我是用桥接还是NAT方式连接.登陆系统以后,我尝试连接网络失败,尝试执行 ...

  5. 关于电商ERP的想法

    原文地址: http://www.chinaodoo.net/thread-465-1-1.html 试用了下odoo的淘宝订单处理模块,从整个业务流程上已经打通,如果要求不是很高的话,现有的功能基本 ...

  6. 【tensorflow】1.安装Tensorflow开发环境,安装Python 的IDE--PyCharm

    ================================================== 安装Tensorflow开发环境,安装Python 的IDE--PyCharm 1.PyCharm ...

  7. insert into select 多个表

    INSERT INTO user_auth(userid, auth_plane_id) select user.user_id AS userid, plane.id AS auth_plane_i ...

  8. Asp.Net Core WebAPI入门整理(四)参数获取

    一.总结整理,本实例对应.Net Core 2.0版本 1.在.Net Core WebAPI 中对于参数的获取及自动赋值,沿用了Asp.Net  MVC的有点,既可以单个指定多个参数,右可以指定Mo ...

  9. Python集合模块collections

    collections collections是Python内建的一个集合模块,提供了许多有用的集合类. namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: ...

  10. django的日志发往http server

    配置示例: # https://docs.djangoproject.com/zh-hans/2.1/topics/logging/ LOGGING = { , 'disable_existing_l ...