您的位置:首页 > 编程语言 > Java开发

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

2014-08-23 00:03 786 查看

同步容器类

同步容器类包括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()等方法,所以必要的时候也需要对它们进行客户端加锁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 并发 多线程