同步容器类

Vector、HashTable,我用的很少;Vecotr的实现和ArrayList挺接近的,不同的是Vector中很多的方法都用synchronized进行了同步。在不强调线程安全地时候用ArrayList,在需要线程安全地时候用Vector。
实现线程安全的方法:把它们的状态封装起来,并对每个公有方法都进行同步,使得每次都只有一个线程能访问容器的状态。

同步容器类问题

在某些情况下需要额外的客户端加锁来保护复合操作:

  1. 迭代,遍历容器中所有元素
  2. 跳转,根据当前顺序找到一下个元素
  3. 条件运算,若没有则添加

执行"先检查再运行"的demo

 public class VectorDemo {
// 获取最后一个元素
public static Object getLast(Vector list) {
int lastIndex = list.size() - 1;
return list.get(lastIndex);
}
// 删除最后一个元素
public static void deleteLast(Vector list) {
int lastIndex = list.size() - 1;
list.remove(lastIndex);
}
}

在客户端中给Vector加上锁,获得一个线程安全的版本:

 public class VectorDemo {
// 获取最后一个元素
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);
}
}
}

支持客户端加锁,可以创建一些新的操作,只要知道应该使用哪一个锁,那么这些新的操作就与容器的其他操作一样都是原子操作。在这个例子中getLast和deleteLast与Vector中其他的方法都共享一把锁,也就是Vector实例自己,同一时刻只能进入其中的一个synchronized代码块中。

在同步容器类中,这些复合操作在没有客户端加锁的情况下仍然是线程安全的,在其他线程并发修改容器的时候,可能会有意料之外的行为。

两个方法都是线程安全的,但是组合起来会导致异常。可以在客户端加锁来解决不可靠迭代的问题,但是要牺牲一些伸缩性。通过在迭代期间持有Vector的锁可以防止其他线程在迭代期间修改Vector。

迭代器与ConcurrentModificationException

对容器进行迭代的标准方式都是用Iterator。在同步容器类中,进行迭代时并没有考虑到并发修改,而是用的"及时失败",终于搞懂了快速失效了。这意味着在迭代时容器被修改将会抛出一个ConcurrentModificationException异常。

这种及时失败的迭代器并不是一种完备的处理机制,而只是善意地捕获并发错误,因此只能作为并发问题的预警指示器。采用的方法是,将计数器的变化与容器关联起来:如果在迭代期间计数器被修改,那么hasNext或next将抛出ConcurrentModification。然而这种检查是在没有同步的情况下进行的,因此可能会看到失效值,而迭代可能并没有意识到已经发生了修改。

为什么不希望在迭代的时候加锁:

  1. 容器的规模很大,或者在每个元素上执行的操作时间很长,那么这些线程将长时间等待。
  2. 一直持有一个锁,可能产生死锁,降低程序的可伸缩性,持有锁的时间越长,锁上的竞争越激烈,如果许多线程都等待着锁被释放,那么将极大地降低吞吐量和CPU的利用率。

隐藏迭代器

加锁可以防止迭代器抛出ConcurrentModificationException,但是要记住在所有对共享容器进行迭代的地方都需要加锁。

如果状态与保护它的同步代码之间相隔越远,那么开发人员就越容易忘记在访问状态的时候使用正确的同步。正如封装对象的状态有助于维持不变性的条件一样,封装对象的同步机制同样有助于确保实施同步策略。

容器的hashCode和equals方法同样会间接地执行迭代操作,当容器所谓另一个容器的元素或者键值时就会出现这种情况。

Java并发编程(十三)同步容器类的更多相关文章

  1. Java并发编程:同步容器

    Java并发编程:同步容器 为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch). ...

  2. 【转】Java并发编程:同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch).今天我们就来讨论下同步容器. ...

  3. 8、Java并发编程:同步容器

    Java并发编程:同步容器 为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch). ...

  4. Java并发编程之同步

    1.synchronized 关键字 synchronized 锁什么?锁对象. 可能锁对象包括: this, 临界资源对象,Class 类对象. 1.1 同步方法 synchronized T me ...

  5. Java并发编程:同步锁、读写锁

    之前我们说过线程安全问题可以用锁机制来解决,即线程必要要先获得锁,之后才能进行其他操作.其实在 Java 的 API 中有这样一些锁类可以提供给我们使用,与其他对象作为锁相比,它们具有更强大的功能. ...

  6. Java并发编程之同步/并发集合

    同步集合 Java中同步集合如下: Vector:基于数组的线程安全集合,扩容默认增加1倍(ArrayList50%) Stack:继承于Vector,基于动态数组实现的一个线程安全的栈 Hashta ...

  7. Java并发编程基础——同步

    一.synchronized 关键字 1)synchronized 锁什么?锁对象.可能锁对象包括: this, 临界资源对象,Class 类对象.如同下面例子所示: package cn.test. ...

  8. Java并发编程之同步辅助类

    CountDownLatch 在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待,基于AbstractQueuedSynchronizer实现,state初始化为count,每cou ...

  9. java并发编程目录

    java并发编程目录 Java多线程基础:进程和线程之由来 JAVA多线程实现的四种方式 Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition Jav ...

  10. Java并发编程、多线程、线程池…

    <实战java高并发程序设计>源码整理https://github.com/petercao/concurrent-programming/blob/master/README.md Ja ...

随机推荐

  1. Mac Screen Capture Shortcuts

    Here's How:   To capture the entire desktop, press Command-Shift-3. The screen shot will be automati ...

  2. Shell中 调用/引用/包含 另外的脚本文件的两种方法

    脚本 first (测试示例1) #!/bin/bash echo 'your are in first file' 问)在当前脚本文件中调用另外一个脚本文件? 方法一: 使用 source 脚本 s ...

  3. Instant Run 的操作影响到了代码,导致Android App启动闪退的问题

    转自yuhc163原文android启动应用java.lang.NoClassDefFoundError: Class not found using the boot class loader; n ...

  4. 用Emmet写CSS3属性会自动添加前缀

    CSS3的很多属性都包含浏览器厂商前缀,用Emmet写CSS3属性会自动添加前缀,比如输入trs 会展开为: -webkit-transition: prop time; -moz-transitio ...

  5. 大数据的开始:安装hadoop

    为实现全栈,从今天开始研究Hadoop,个人体会是成为某方面的专家需要从三个方面着手 系统化的知识(需要看书或者比较系统的培训) 碎片化的知识(需要根据关注点具体的深入的了解) 经验的积累(需要遇到问 ...

  6. pwn2own

    Pwn2Own是全球最著名的黑客大赛之一,由美国五角大楼入侵防护系统供应商TippingPoint的DVLabs赞助,今年已经是第六届. 1比赛规则 参赛黑客们的目标是4大主流网页浏览器——IE.Fi ...

  7. 9.11排序与查找(三)——给定一个排序后的数组,包括n个整数,但这个数组已被旋转过多次,找出数组中的某个元素

    /**  * 功能:给定一个排序后的数组.包括n个整数.但这个数组已被旋转过多次,次数不详.找出数组中的某个元素.  * 能够假定数组元素原先是按从小到大的顺序排列的.  */ /** * 思路:数组 ...

  8. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-点动面板的每个按钮含义

    参考下面的图示     更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com/acetaohai123   我的在线论坛: http://csrobot.g ...

  9. 微信小程序 - 文本框显示限制最大长度

    wxml <view class='textarea-count'> <textarea placeholder='请输入文字' bindinput="getWords&q ...

  10. Unity3D在WebPlayer模式下的异常上报探索

    原地址:http://www.cnblogs.com/hisiqi/archive/2013/07/21/3203527.html 我们知道,Unity3D在WebPlayer的发布模式下是沙箱环境中 ...