Java多线程——同步容器类
1、同步容器类
同步容器类包括Vector和Hashtable,是早期JDK的一部分,这些类实现的方法是:将它们的状态封装起来,并对每个共有的方法进行同步,使得每个线程只有一个线程能访问它们。
1.1 、同步容器类问题
同步类容器都是线程安全的,但在某些场景下可能需要加锁来保护复合操作。复合类操作如:迭代(反复访问元素,遍历完容器中的所有元素)、跳转(根据指定的顺序找到当前元素的下一个元素)、以及条件运算。这些复合操作在多线程并发的修改容器时,可能会表现出意外的行为。如下面的代码:
for(int i = 0; i < vector.size(); i++){
doSomething(vector.get(i));
}
单线程中,这是成立的,但是在多线程中,有其他的线程并发的修改vector,则可能会导致麻烦,假如在对vector进行迭代时,另一个线程删除了一个元素,则可能会抛出ArrayIndexOutOfBoundsException异常。但是我们可以通过客户端加锁的机制来解决该问题,如下:
synchronized (vector) {
for(int i = 0; i < vector.size(); i++){
doSomething(vector.get(i));
}
}
1.2 迭代器与ConcurrentModificationException
当容器在迭代过程中被修改,就会抛出ConcurrentModificationException异常。如果想在迭代过程中,不被其他线程修改容器,还得加锁,或者克隆一个副本出来,在副本上进行迭代,这样就避免了抛出ConcurrentModificationException异常。
1.2 隐藏迭代器
虽然加锁可以防止迭代器抛出ConcurrentModificationException异常,但你必须要记住在所有的对所有共享容器进行迭代的地方都需要加锁。因为在某些情况下,迭代器有隐藏起来,比如我们在输出一个容器的时候,会间接的调用toString()方法,标准容器的toString方法将对容器进行迭代。容器的hashCode,equals,containsAll等方法,都会对容器进行迭代,这些间接的迭代都可能会抛出ConcurrentModificationException异常。
2、并发容器
同步容器将所有对容器状态的访问都串行化来实现它们的安全性。这中方法的代价是严重降低并发性,当多个容器竞争容器的锁时,吞吐量将严重降低。并发容器是针对多个线程并发访问设计的,通过并发容器代替同步容器,可以极大的提高伸缩性并降低风险。
java5.0之后提供了多种并发容器来改善同步容器的性能,如ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentSkipListMap等;我们对它们进行详细介绍。
2.1 ConcurrentHashMap
ConcurrentHashMap并不是将每个方法都在同一个锁上同步并使得每次只能一个线程访问容器,而是使用一种粒度更细的加锁机制来实现更大程度的共享,这种机制被称为分段锁(Lock Striping),这种加锁机制带来的结果是,在并发访问的环境下将实现更高的吞吐量,在单线程上只损失非常小的性能。
这篇文章详细的介绍了ConcurrentHashMap的原理:http://www.cnblogs.com/ITtangtang/p/3948786.html。
2.2 CopyOnWriteArrayList
CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。详细的介绍看这里:http://www.cnblogs.com/dolphin0520/p/3938914.html
Java多线程——同步容器类的更多相关文章
- Java多线程同步问题的探究
一.线程的先来后到——问题的提出:为什么要有多线程同步?Java多线程同步的机制是什么? http://www.blogjava.net/zhangwei217245/archive/2010/03/ ...
- 转:关于JAVA多线程同步
转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖 ...
- java多线程同步
一篇好文:java多线程机制同步原则 概括起来说,Java 多线程同步机制主要包含如下几点:1:如果一个类包含一个或几个同步方法,那么由此类生成的每一个对象都配备一个队列用来容纳那些等待执行同步的线程 ...
- Java多线程-同步:synchronized 和线程通信:生产者消费者模式
大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...
- 转:java多线程--同步容器
java同步容器 在Java的集合容器框架中,主要有四大类别:List.Set.Queue.Map.List.Set.Queue接口分别继承了Collection接口,Map本身是一个接口.注意Col ...
- Java多线程同步 synchronized 关键字的使用
代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...
- Java多线程---同步与锁
一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动 ...
- Java多线程同步的方法
一 synchronized关键字 1.synchronized实现原理: ---基于对象监视器(锁) java中所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数 ...
- Java 多线程同步的五种方法
一.引言 闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子 ...
随机推荐
- springboot中开发热部署(devtools)
1.只需要在pom文件中引入devtools的依赖即可 <dependency> <groupId>org.springframework.boot</groupId&g ...
- Qt's Undo Framework
Overview of Qt's Undo Framework Introduction Qt's Undo Framework is an implementation of the Command ...
- 配置Linux防火墙
配置防火墙(服务器安全优化)(转) 安全规划:开启 80 22 端口并 打开回路(回环地址 127.0.0.1) # iptables –P INPUT ACCEPT # iptables –P O ...
- 初识STM32
1.什么是STM32 A.ST是意法半导体,一个公司名,即SOC厂商,生产芯片的厂商.ARM公司是IP厂商,即只生产内核的厂商. B.M-Microelectronics的缩写,表示微控制器,大家注意 ...
- 【美食技术】家庭自制DIY鸡蛋饼和疙瘩汤早餐视频教程
鸡蛋饼制作方法 食材准备面粉 150g鸡蛋饼 鸡蛋饼鸡蛋 2个盐 适量水 适量(约300ml)油 20g荵花适量也可根据自己喜好准备一些调味料. 做法 鸡蛋饼是一种家常点心,做法很多,这里提供3种. ...
- 479. Largest Palindrome Product
class Solution { public: int largestPalindrome(int n) { vector<,,,,,,,}; ]; } }; 这里的穷举法,你不得不服
- HBase-1.2.1和Phoenix-4.7.0分布式安装指南
目录 目录 1 1. 前言 2 2. 概念 2 2.1. Region name 2 3. 约定 2 4. 相关端口 3 5. 下载HBase 3 6. 安装步骤 3 6.1. 修改conf/regi ...
- 排序:快速排序Quick Sort
原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序 ...
- C++智能指针shared_ptr
shared_ptr 这里有一个你在标准库中找不到的—引用数智能指针.大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章.最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引 ...
- MySQL性能调优与架构设计——第9章 MySQL数据库Schema设计的性能优化
第9章 MySQL数据库Schema设计的性能优化 前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就 ...