SynchronizedCollection简介

  SynchronizedCollection是Collections下所有现场安全集合的父类,并发安全集合可以分为三类,一种是比较老的实现,例如vector,一种是concurrent包下的,另外一种就是SynchronizedCollection。他是通过对并发不安全的集合进行包装,使得线程安全。

  实现介绍

  上面也说了,他是通过对并发不安全的集合进程包装的。思想上就是加了一个object锁,然后在每个方法上加入锁的逻辑。

  static class SynchronizedCollectionimplements Collection, Serializable {

  final Collectionc; // Backing Collection

  final Object mutex; // Object on which to synchronize

  SynchronizedCollection(Collectionc, Object mutex) {

  this.c = Objects.requireNonNull(c);

  this.mutex = Objects.requireNonNull(mutex);

  }

  ....

  }

  SynchronizedCollection有两个成员变量,一个是被包装的集合对象c,一个是用来作为锁的对象mutex。集合对象和锁对象都可以通过构造函数传入。

  大家如果看过vector的实现的话,大概明白接下来的实现手段了,就是加锁!

  public int size() {

  synchronized (mutex) {return c.size();}

  }

  public boolean isEmpty() {

  synchronized (mutex) {return c.isEmpty();}

  }

  public boolean contains(Object o) {

  synchronized (mutex) {return c.contains(o);}

  }

  public Object[] toArray() {

  synchronized (mutex) {return c.toArray();}

  }

  publicT[] toArray(T[] a) {

  synchronized (mutex) {return c.toArray(a);}

  }

  是不是看了实现的你也是微微一下,这里就是通过synchronized 加锁mutex。然后在代码块里执行原来的集合的方法,由于每个方法都被加上了锁,所以集合也成为了并发安全的集合。

  安全性依靠的就是集合被覆写,如果没有被覆写,那么线程安全性也就不保证了。很多人也很好奇,这都是包装安全了,为啥还会这么说。

  下面就展示一个例外。

  public Iteratoriterator() {

  return c.iterator(); // Must be manually synched by user!

  }

  iterator方法没有被覆写!也就是说使用迭代器迭代的时候,线程是不安全的,所以这个方法的也加了注释,需要用户加同步。

  很多时候大家的第一反应就是给iterator加synchronized 的就可以。但是真的是这样吗?

  我们来推演一下,如果在iterator方法上加锁,那么确实保证了iterator方法是线程安全的,在并发的情况下,只会有一个线程操作成功,成功获取到iterator对象。但是接下来呢,我们要拿到iterator对象进行迭代,此时如果集合有增删操作是可以的,因为iterator对象的操作完全没有锁竞争。此时迭代就会出错。

  装饰者模式

  SynchronizedCollection这种通过实现Collection接口,然后自己把接口的方法都实现了一遍,并且使用了组合的方式,对每个方法增加了新的功能,最后还返回接口对象,面向接口编程。这就是典型的装饰者模式。

  为了增加新的功能,不断的继承接口,实现自己的新逻辑,而且对调用端屏蔽了操作。如果说在增加一个需求,就是需要一个集合操作完之后就删除一个元素。那么只要实现Collection接口,对每个方法的调用都做一个删除的操作,并且执行传入的集合对象就可以了,在生成对象的时候,不断的构造对象传入。如果功能不需要了,例如不需要线程安全的需求了,那么只要在生成对象的时候,直接去掉SynchronizedCollection就可以了。

  装饰者模式的优点就是对外面向接口,对调用者屏蔽细节。然后功能拆分比较细,可以进行比较灵活的组装。

  iterator的问题,其实也是装饰者模式的弊端,就是他对包装者的功能扩展是有一定限制的。他可以对他包装的对象进行扩展,但是并不能对包装对象里依赖的对象进行太多的干预。

  java中装饰者模式的应用

  除了上面的SynchronizedCollection。java中另外一个典型的案例就是io。

  java的io是可以不停的功能扩展的。

  FileInputStream是基础的字节io

  InputStreamReader可以对FileInputStream进行功能扩充

  BufferedReader对Reader可以再进程扩充

  其实大家使用的时候的一些缺点也暴露出来了,就是功能扩充的限制问题,我们一旦装饰到BufferedReader,就不会再去使用read方法了,主要使用readLine这个功能了,其实接口并没有这个方法,所以我们使用io的时候已经不再是面向接口了,更多的是面向了具体的实现,因为在文件的场景下。接口并不能彻底抽象全部功能,他只能有共有的。

  总结

  java中有两个地方使用了装饰者模式,io,SynchronizedCollection。

  SynchronizedCollection对每个方法进行了功能的扩充,但是对包装类里的成员变量不能控制。

  io增加了功能,但是功能有更多的特性,最后反而是面向了实现类编程。

  装饰者模式的好处是灵活,功能扩展方便。坏处就是功能扩展有限制,一个限制在接口,一个限制在被装饰者内部的成员变量。

从SynchronizedCollection说起的更多相关文章

  1. 用Collections.synchronizedCollection创建线程安全的集合、列表。。。

    Collection c=Collections.synchronizedCollection(new ArrayList()); List list=Collections.synchronized ...

  2. java - 并发集合 Vector、synchronizedCollection、CopyOnWriteArrayList之间的区别。

    概要 JDK中提供ArrayList集合方便我们对集合内元素进行增删改查,但是ArrayList为了能够在单线程中快速进行操作其设计并不支持多线程进行操作.ArrayList在多线程环境下可能会产生j ...

  3. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  4. Collection集合

    一些关于集合内部算法可以查阅这篇文章<容器类总结>. (Abstract+) Collection 子类:List,Queue,Set 增: add(E):boolean addAll(C ...

  5. C#泛型方法解析

    C#2.0引入了泛型这个特性,由于泛型的引入,在一定程度上极大的增强了C#的生命力,可以完成C#1.0时需要编写复杂代码才可以完成的一些功能.但是作为开发者,对于泛型可谓是又爱又恨,爱的是其强大的功能 ...

  6. Java Hashtable的实现

    先附源码: package java.util; import java.io.*; /** * This class implements a hash table, which maps keys ...

  7. Java基础应用

    Java集合类解析 List.Map.Set三个接口,存取元素时,各有什么特点? List 以特定次序来持有元素,可有重复元素.Set 无法拥有重复元素,内部排序.Map 保存key-value值,v ...

  8. Java集合面试题

    1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用,Java1 ...

  9. System.Collections.Generic的各容器类的用法

    演示System.Collections.Generic的各容器类的用法. 包括:Dictionary,KeyValuePair,SortedDic tionary,SortedList,HashSe ...

随机推荐

  1. 利用AES算法加密数据

    准备工作: 模块安装问题: 首先在python中安装Crypto这个包 但是在安装模块后在使用过程中他会报错 下面是解决方法: pip3 install pycrypto 安装会报错 https:// ...

  2. 【opencv入门篇】 10个程序快速上手opencv【下】

    导言:本系列博客目的在于能够在vs快速上手opencv,理论知识涉及较少,大家有兴趣可以查阅其他博客深入了解相关的理论知识,本博客后续也会对图像方向的理论进一步分析,敬请期待:) 上篇传送:http: ...

  3. 解决scrollView中嵌套编辑框导致不能上下滑动的问题

    EditText设置maxLines之后,文本行数超过maxLines,会网上折叠,上下滑动能够浏览全部文本. 若EditText外层有scrollView.在EditText上下滑动,不会像正常情况 ...

  4. 关于softnet的加密硬件狗 也就是所谓的赛孚耐

    SuperDog-R-2.2.1.iso 上面那个文件就是光盘里面的东西.你买了他们的产品 自然后带着这个玩意. 按照默认路径安装一下. 安装完毕如下图:

  5. vertical-align和line-height的深入应用

    vertical-align和line-height的深入应用 本文的重点是了解vertical-align和line-height的使用 涉及到的名词:基线,底端,行内框,行框,行间距,替换元素及非 ...

  6. PL/SQL 创建用户及权限操作

    1.创建User create user user01 identified by user01, 2.赋予连接数据库的权限 grant connect to user01; 3.把user00的表E ...

  7. [笔记]Python中模块互相调用的例子

    python中模块互相调用容易出错,经常是在本地路径下工作正常,切换到其他路径来调用,就各种模块找不到了. 解决方法是通过__file__定位当前文件的真实路径,再通过sys.path.append( ...

  8. 235. Lowest Common Ancestor of a Binary Search Tree(LCA最低公共祖先)

      Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the ...

  9. Spring 实现数据隔离

    需求 用户数据要同时支持在mysql和redis进行管理.存储. 思路 利用spring的注解,在配置中指定存储类型,启动时识别并选择对应的实现类. 代码 1. 用户管理的接口类 public int ...

  10. 关于Socket和ServerSocket类详解

    Socket类 套接字是网络连接的一个端点.套接字使得一个应用可以从网络中读取和写入数据.放在两个不同计算机上的两个应用可以通过连接发送和接受字节流.为了从你的应用发送一条信息到另一个应用,你需要知道 ...