对数据同步访问封装的策略
我们经常操作一些本身不是线程安全的对象时,在多线程的环境下就会考虑到要采取一些措施来处理。一些典型比如说用synchronized来同步,有的如果情况允许的话使用ThreadLocal变量,还有的会将对象变成immutable的方式。当然,每种方法都需要根据具体问题来分析,不能在保证高并发性和线程安全的情况下完全通用。
同步的数据结构
有一个比较常见的用法就是当我们要访问一些集合类的时候。大多数的集合类比如ArrayList, HashMap之类的都不是线程安全的。为了保证线程安全,我们可能需要用到前面提到的一些同步策略。常见的一种如下:
public class PersonSet { private final Set<Person> mySet = new HashSet<Person>(); public synchronized void addPerson(Person p) { mySet.add(p); } public synchronized boolean containsPerson(Person p) { return mySet.contains(p); } }
这种方法用到一个比较好的思路,就是将一些我们需要多线程访问的数据封装起来。然后对他们的访问操作进行线程同步。这样我们要访问修改的地方就在这个被封装的地方,也方便维护。
从这种用法我们看到的思路就是封装线程不安全的数据结构,通过这个封装对象添加一些同步的机制来保证最终访问的线程安全。那么,这种思路还有没有其他应用的示例呢?在java中间有一些典型的类,如Collections.synchronizedList, Collections.synchronizedSet等。他们就是用到了这样的思路。
设计思路
一个典型的synchronizedList用法如下:
List<Person> persons = new ArrayList<Person>(); List<Person> securePersons = Collections.synchronizedList(persons);
通过将我们线程不安全的数据传入synchronizedList方法,返回的还是一个list,不过对它的访问就变成线程安全的了。比较有意思吧?通过前面提到的将数据封装起来,然后提供同步机制,我们也就可以猜到,这种方式也是通过同样的手法。
现在,如果我们足够好奇的话,再进一步想想。最前面那个示例对数据进行了封装,再次访问这个arrayList的时候,实际上是通过访问封装对象提供的方法来使用的。而我们这边进行了封装之后居然和可以把它当成一个List来用。那么,这说明了什么呢?说明我们这个封装它的类肯定提供了和List一样的接口。如果我们对某些设计模式比较熟悉的话,再回想这么一句,实现相同的接口,封装了另外一个对象,对这么一个对象增加了某些功能,但是还能当成同样接口的对象用。
呵呵,像什么呢?好像很熟悉的感觉,有点decorator pattern的感觉,也有点像adapter。
如果我们深入代码的细节去探索的话,会发现它实际的实现方式是用到了decorator pattern。代码本身并不负责,具体的代码细节就不去赘述了。他们的类结构关系如下图:
这是一个稍微复杂一点的decorator pattern实现,每个进行封装的类如SynchronizedList, SynchronizedSet都继承自SynchronizedCollection,其他的需要被封装的类如ArrayList, LinkedList和SynchronizedCollection实现同样的接口。我们再对照一下典型的decorator pattern类图结构:
这里头,decorator就相当于一个二道贩子。它把一些现成的需要封装的对象拿过来,然后按照同样的规格(接口)在折腾出一个具有一点新功能的对象。想到这里,一种山寨的感觉油然而生。
总结
我们为了提供一个线程安全的数据结构而采用了一种封装对象。这样,用户就可以很方便的使用一个封装调用而得到所期望的同步效果。这样比直接去加synchronized要方便多了,更加不容易出错。在这么一个简单易用的外表下面,还是隐藏着一些封装的复杂手法。唉,扮靓是需要代价的。
相关推荐
concurrency:Java Concurrency in Practice源代码
The Art of Concurrency: A Thread Monkey's Guide to Writing Parallel Applications PDF文件,很清晰,,, Intel资深工程师分享并发编程知识及内幕技术 详述如何在各种算法中使用线程化方法 开发并行代码算法...
Java Concurrency in Practice 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者...
java-concurrency:代码审查清单
Using the concurrency building blocks in java.util.concurrent Performance optimization dos and don'ts Testing concurrent programs Advanced topics such as atomic variables, nonblocking algorithms, ...
Java Concurrency in practice
<<java并行编程>>英文版chm格式,英文名称<Java Concurrency in Practice>,一直想买这本书,但总是缺货,找到了电子版,分享给大家。 Java Concurrency in Practice By Brian Goetz, Tim Peierls, Joshua Bloch,...
Java Concurrency Programming Lessons.
Java并发 Java并发教程
Java concurrency in Practice高清pdf,带目录标签,Java并发实战
Java Concurrency in Practice JAVA并发编程实践中文版(全)第二部分
java concurrency in practice
Java Concurrency in Practice源码
java8 源码 并发操作合集 这是一个关于并发的系列。以实战为驱动,了解并发编程中的那些骚操作。文中的示例代码和部分解释来源于网络,你可以把这个系列当做一本工具书,想不起来的时候来看一看,顺便star一发也是...
正规PDF版本的 Java Concurrency In Practice。 经典著作,学习有益!
Get an easy introduction to reactive streams in Java to handle concurrency, data streams, and the propagation of change in today's applications. This compact book includes in-depth introductions to ...
java concurrency programming
Concurrent_Programming+Java Concurrency in Practice+langspec