学习同步容器类

来源:互联网 发布:斗战三国志进阶数据 编辑:程序博客网 时间:2024/06/05 14:55

在上篇博客中介绍了一下关于线程带来的危害,那么这篇博客来说说JAVA平台中的线程安全类的并发基础构建模块。

 

在介绍Java平台中的线程安全类的并发基础构建模块之前,要先介绍一些关于如何设计线程安全类的一些基础知识。

在线程安全的程序中,虽然可以将程序所有状态都保存在共有的静态域中,但与哪些将状态封装起来的程序相比,线程安全更加的得以验证,并且在修改的时候也不太好保证线程的安全性。那么其实我们可以通过封装的技术可以在不对整个程序进行分析的情况下判断一个类是否是线程安全的。

 

我们如果想要设计出线程安全的类,需要包括下面三个基础,

1.        找出构成对象状态的所有变量

2.        找出约束状态变量的不变性条件

3.        建立对象状态的并发访问管理策略

有了这些基础知识之后,来看一下JAVA平台类库中的并发基础构建模块,在JAVA平台类库中有非常丰富的这些模块用来帮助建立线程安全类的,例如同步容器类、并发容器等。

 

这篇博客介绍同步容器类,下篇博客介绍一下并发容器。

 

在JAVA平台中同步容器类包括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也是如此的。那么这就是在JAVA平台中利用同步容器类创建线程安全的类的实现。

参考《Java 并发编程实战》

0 0
原创粉丝点击