Java 并发编程之基础构建模块

同步容器类

同步容器类包括Vector和Hashtable,还有一些同步的封装器是由Collections.synchironzedXxx等工厂方法创建的,这些类的实现线程安全的方式是通过把状态封装起来,并对每个公有方法都进行同步,使得每次只有一个线程能访问容器的状态。就是上一篇说的客户端加锁的方法。

同步容器类的问题

同步容器类也有些问题,比如Vector上的getLast()和DeleteLast()方法,但如果两个线程分别调用这两个方法的时候那个Getlast()恐怕就会出Nullpointer的异常了。所以我们采用客户端加锁的方式解决这个问题

puclib static Object getLast(Vector list){
	synchroinzed(list){

	}
}
对deleteList也用这个同步

同时,vector里边的迭代也是有一定风险的。但是如果对其也加上和上面一样的锁的话,会降低并发性。这个加不加视情况而论。


迭代器和ConcurrentModificationException

几乎所有的容器类都没有消除复合操作的问题,当它们发现在迭代过程中被修改时就会抛出ConcurrentModificationException异常。这种处理并不完备,只能作为并发容器的预警指示器,它们采用的实现方式是,将计数器的变化和容器关联起来,如果在迭代期间计数器被修改,那么 hasnext和next将抛出这个异常。如果容器规模很大,那么如果对其进行了客户端加锁之后,其它线程要等待很长时间,那么极大地降低吞吐量和CPU的利用率。


如果不希望在迭代期间对容器加锁,那么 一种替代方法就是clone容器,并在副本上进行迭代。副本封闭在线程内,因此其它线程不会在迭代过程中对其进行修改。这样就避免抛出上面的这个异常,并且在克隆过程中仍然需要对容器加锁。


隐藏迭代器

private final Set<Interger> set=new Hashset<Interger>;
public void prinln(){
 System.out.prinln(set);
}

在程序输出set的时候,会隐式的 调用迭代器。还有比如Contailall(),removeAll(),Retainall()等方法,所以必要的时候也需要对它们进行客户端加锁。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值