`
frank-liu
  • 浏览: 1682336 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java concurrency: synchronized collections

 
阅读更多

对数据同步访问封装的策略

        我们经常操作一些本身不是线程安全的对象时,在多线程的环境下就会考虑到要采取一些措施来处理。一些典型比如说用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要方便多了,更加不容易出错。在这么一个简单易用的外表下面,还是隐藏着一些封装的复杂手法。唉,扮靓是需要代价的。

参考资料

java concurrency in practice

openjdk

  • 大小: 71.5 KB
分享到:
评论
3 楼 xiaolong8 2014-11-06  
frank-liu 写道
xiaolong8 写道
装饰模式是“新增行为”,而代理模式是“控制访问”。线程同步访问属于控制访问。

所以我觉得应该是代理模式。

我觉得它这是用装饰模式的样式实现了代理的行为,从访问控制的角度来说,它们两者的界限很模糊。



后来我想想还是是属于装饰模式,因为代理模式的控制访问能禁止,而这里只是让各线程串行访问执行,并没有去真正的控制访问。而是对访问方式作了串行处理,可以理解为一个对访问方式的修饰。
2 楼 frank-liu 2014-11-01  
xiaolong8 写道
装饰模式是“新增行为”,而代理模式是“控制访问”。线程同步访问属于控制访问。

所以我觉得应该是代理模式。

我觉得它这是用装饰模式的样式实现了代理的行为,从访问控制的角度来说,它们两者的界限很模糊。
1 楼 xiaolong8 2014-10-31  
装饰模式是“新增行为”,而代理模式是“控制访问”。线程同步访问属于控制访问。

所以我觉得应该是代理模式。

相关推荐

    java-concurrency:java并发教程

    3. **线程安全包装器(Thread-Safe Wrappers)**:Java提供了一些工具类,如`Collections.synchronizedXXX`方法,可以将非线程安全的集合类转化为线程安全的。此外,`java.util.concurrent`包提供了许多线程安全的...

    Java Concurrency In Practice.pdf

    书中介绍了Java集合框架中的一些同步集合类,如`Collections.synchronizedList`等,并探讨了它们的使用场景。 ##### 5.2 并发集合 并发集合是专为多线程环境设计的集合类型,它们在设计上更加注重高并发性能。书中...

    Java 7 Concurrency Cookbook

    useful mechanisms included in Version 7 of the Java concurrency API, so you will be able to use them directly in your applications, which are as follows: f f t e n . d u o l Basic thread management w....

    Android代码-java-concurrency-patterns

    Synchronized Collections Concurrent Collections CopyOnWriteArrayList ConcurrentHashMap Blocking Queue Executors Fixed Thread Pool Cached Thread Pool Single Thread Pool Scheduled Thread Pool ...

    java_concurrency_in_practice

    探讨了如何通过`Collections.synchronizedMap`等工具类创建线程安全的集合。 - **5.2 并发集合** 介绍了一系列专门为并发环境设计的集合类,如`ConcurrentHashMap`。 - **5.3 阻塞队列和生产者-消费者模式** ...

    《Java Concurrency in Practice》代码示例

    《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著。这本书深入浅出地探讨了Java平台上的多线程和并发编程,提供了丰富的...

    java_concurrency_in_practice:《Java并发编程实战》学习Demo

    - **线程安全类型**:Java提供了一些线程安全的集合类,如`Vector`、`Collections.synchronized*`方法包装的集合、`ConcurrentHashMap`等。 3. **同步机制** - **synchronized**:它可以保证同一时间只有一个线程...

    Core Java Concurrency

    - **简介**:Java SE 5引入了一组新的锁类,它们提供了比传统`synchronized`更灵活和更强大的功能。 - **示例**: - `ReentrantLock`:可重入锁,支持公平性和非公平性锁。 - `ReadWriteLock`:读写锁,允许多个读...

    Java.Concurrency.in.Practice.pdf

    并发集合(Synchronized Collections)、并发集合(Concurrent Collections)、阻塞队列(Blocking Queues)以及生产者-消费者模式(Producer-Consumer Pattern)是构建并发程序的基石。 4. **同步器...

    concurrency-in-java:Java并发入门

    - **线程的创建**:Java提供了两种创建线程的方式,一是通过实现`Runnable`接口,二是继承`Thread`类。两者各有优缺点,前者更符合面向对象设计,后者可以直接调用`start()`方法执行。 - **线程的生命周期**:Java...

    Java任小龙版基础笔记.zip

    7. **多线程**:Java内置对多线程的支持,学习如何创建和管理线程,理解线程同步和互斥的概念,如synchronized关键字和wait/notify机制。 8. **反射与注解**:反射机制允许程序在运行时动态地获取类的信息并调用其...

    Java 并发核心编程原文+译文

    9. **线程安全的类和方法**:Java API中有些类和方法被声明为线程安全,比如`Collections.synchronizedXXX`方法、`System.currentTimeMillis()`等。了解这些类和方法的特性,可以帮助我们避免不必要的同步。 10. **...

    Java 多线程与并发(7-26)-JUC - 类汇总和学习指南.pdf

    2.Collections: Collections 部分提供了一些并发集合类,例如 CopyOnWriteArrayList、ConcurrentHashMap 等,这些类可以在多线程环境下安全地使用。 3.Atomic: Atomic 部分提供了一些原子类,例如 ...

    Java高级编程资料,java高级编程技术,Java

    书籍如《Effective Java》、《Java Concurrency in Practice》和《Head First Java》等,都是学习Java高级编程的经典之作。在线资源如Oracle的Java Tutorials和Stack Overflow上的问答,为解决实际问题提供了大量...

    Java——JUC

    Java并发编程是Java开发中的重要领域,而Java并发工具包(Java Concurrency Utility,简称JUC)则是Java标准库提供的一套强大而丰富的工具,它极大地简化了多线程环境下的编程工作。JUC主要包含在`java.util....

    Learn.Java.for.Android.Development_Apress.2010+src

    the Reflection API, String, StringBuffer, System, the Threading API, the collections framework, the concurrency utilities, the internationalization APIs, the Preferences API, Random, the Regular ...

    java学习资料.zip

    10. **并行与并发(Concurrency)**:介绍Java中的线程和同步机制,如synchronized关键字、volatile变量和java.util.concurrent包。 11. **序列化(Serialization)**:解释如何实现Serializable接口,并探讨其潜在...

    java api中文版chm

    14. **并发编程(Concurrency)**:Java提供了丰富的并发工具类,如`ExecutorService`、`Semaphore`、`CountDownLatch`等,帮助开发者编写高效且线程安全的代码。 15. **JVM内存管理(JVM Memory Management)**:...

Global site tag (gtag.js) - Google Analytics