学习同步容器类
2014-07-28 22:17
99 查看
在上篇博客中介绍了一下关于线程带来的危害,那么这篇博客来说说J***A平台中的线程安全类的并发基础构建模块。
在介绍Java平台中的线程安全类的并发基础构建模块之前,要先介绍一些关于如何设计线程安全类的一些基础知识。
在线程安全的程序中,虽然可以将程序所有状态都保存在共有的静态域中,但与哪些将状态封装起来的程序相比,线程安全更加的得以验证,并且在修改的时候也不太好保证线程的安全性。那么其实我们可以通过封装的技术可以在不对整个程序进行分析的情况下判断一个类是否是线程安全的。
我们如果想要设计出线程安全的类,需要包括下面三个基础,
1. 找出构成对象状态的所有变量
2. 找出约束状态变量的不变性条件
3. 建立对象状态的并发访问管理策略
有了这些基础知识之后,来看一下J***A平台类库中的并发基础构建模块,在J***A平台类库中有非常丰富的这些模块用来帮助建立线程安全类的,例如同步容器类、并发容器等。
这篇博客介绍同步容器类,下篇博客介绍一下并发容器。
在J***A平台中同步容器类包括Vector和Hashtable,当然这两个都是早期JDK版本中的内容。所谓的同步容器类就是将自己的状态封装,并对每个公有方法都进行同步,使得每次只有一个线程能够访问容器的装填。这两个容器中常见的符合操作包括:迭代、跳转以及条件运算,这些操作是线程安全的,但是其他线程并发的修改容器时候,可能会表现出意料之外的行为。
可以看一下下面的例子:
两个方法都会先检查在运行,看似没有任何问题,但是方法从调用者的角度来看,就会出现问题。
线程A在包含10个元素的Vector上调用getLast,同时线程B在同一个Vector上调用deleteLast,这些操作交替执行就会出现数组越界异常。
由于同步容器类支持客户端加锁,因此需要同步容器类通过其自身的锁来保护自己的每个方法。当然通过对自己加锁,可以让getLast和deleteLast成为原子操作,确保了不会发生异常。
那这种情况在迭代中也会出现的,所以这时候也是需要对vector本身进行加锁操作,当然对于hashtable也是如此的。那么这就是在J***A平台中利用同步容器类创建线程安全的类的实现。
参考《Java 并发编程实战》
在介绍Java平台中的线程安全类的并发基础构建模块之前,要先介绍一些关于如何设计线程安全类的一些基础知识。
在线程安全的程序中,虽然可以将程序所有状态都保存在共有的静态域中,但与哪些将状态封装起来的程序相比,线程安全更加的得以验证,并且在修改的时候也不太好保证线程的安全性。那么其实我们可以通过封装的技术可以在不对整个程序进行分析的情况下判断一个类是否是线程安全的。
我们如果想要设计出线程安全的类,需要包括下面三个基础,
1. 找出构成对象状态的所有变量
2. 找出约束状态变量的不变性条件
3. 建立对象状态的并发访问管理策略
有了这些基础知识之后,来看一下J***A平台类库中的并发基础构建模块,在J***A平台类库中有非常丰富的这些模块用来帮助建立线程安全类的,例如同步容器类、并发容器等。
这篇博客介绍同步容器类,下篇博客介绍一下并发容器。
在J***A平台中同步容器类包括Vector和Hashtable,当然这两个都是早期JDK版本中的内容。所谓的同步容器类就是将自己的状态封装,并对每个公有方法都进行同步,使得每次只有一个线程能够访问容器的装填。这两个容器中常见的符合操作包括:迭代、跳转以及条件运算,这些操作是线程安全的,但是其他线程并发的修改容器时候,可能会表现出意料之外的行为。
可以看一下下面的例子:
public static Object getLast(Vector list){ intlastIndex=list.size()-1; returnlist.get(lastIndex); } public static void deleteLast(Vector list){ intlastIndex=list.size()-1; list.remove(lastIndex); }
两个方法都会先检查在运行,看似没有任何问题,但是方法从调用者的角度来看,就会出现问题。
线程A在包含10个元素的Vector上调用getLast,同时线程B在同一个Vector上调用deleteLast,这些操作交替执行就会出现数组越界异常。
由于同步容器类支持客户端加锁,因此需要同步容器类通过其自身的锁来保护自己的每个方法。当然通过对自己加锁,可以让getLast和deleteLast成为原子操作,确保了不会发生异常。
public static Object getLast(Vector list){ synchronized(list){ int lastIndex=list.size()-1; return list.get(lastIndex); } } public static void deleteLast(Vector list){ synchronized(list){ int lastIndex=list.size()-1; list.remove(lastIndex); } }
那这种情况在迭代中也会出现的,所以这时候也是需要对vector本身进行加锁操作,当然对于hashtable也是如此的。那么这就是在J***A平台中利用同步容器类创建线程安全的类的实现。
参考《Java 并发编程实战》
相关文章推荐
- Docker容器学习梳理-容器时间跟宿主机时间同步
- 学习互联网架构第九课(同步类容器)
- 跟着实例学习java多线程8-同步容器类的问题
- Docker容器学习梳理-容器时间跟宿主机时间同步
- java并发编程学习:同步容器与并发容器
- 并发编程与高并发解决方案学习(同步容器)
- java学习笔记之容器的同步与只读控制
- Java学习笔记—多线程(同步容器和并发容器)
- stl学习笔记2(容器,函数对象)
- Java学习:容器(未完成)
- 关于容器输出的学习与简化过程
- [推荐学习]什么是IOC,什么是容器,什么是服务组件,它们和普通用户类的区别
- Ioc容器应用浅析--EasyJF学习
- 孙鑫VC学习笔记:第十六讲 利用关键代码段实现线程间的同步
- STL容器--学习笔记
- 标准模板库(STL)学习指南之List容器
- asp.net同步学习
- 标准模板库(STL)学习指南之List容器
- Java容器类学习心得,欢迎拍砖
- [ASP.NET学习笔记之二]数据集和数据库的同步-DataAdapter的使用