对数据同步访问封装的策略
我们经常操作一些本身不是线程安全的对象时,在多线程的环境下就会考虑到要采取一些措施来处理。一些典型比如说用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要方便多了,更加不容易出错。在这么一个简单易用的外表下面,还是隐藏着一些封装的复杂手法。唉,扮靓是需要代价的。
相关推荐
3. **线程安全包装器(Thread-Safe Wrappers)**:Java提供了一些工具类,如`Collections.synchronizedXXX`方法,可以将非线程安全的集合类转化为线程安全的。此外,`java.util.concurrent`包提供了许多线程安全的...
书中介绍了Java集合框架中的一些同步集合类,如`Collections.synchronizedList`等,并探讨了它们的使用场景。 ##### 5.2 并发集合 并发集合是专为多线程环境设计的集合类型,它们在设计上更加注重高并发性能。书中...
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....
Synchronized Collections Concurrent Collections CopyOnWriteArrayList ConcurrentHashMap Blocking Queue Executors Fixed Thread Pool Cached Thread Pool Single Thread Pool Scheduled Thread Pool ...
探讨了如何通过`Collections.synchronizedMap`等工具类创建线程安全的集合。 - **5.2 并发集合** 介绍了一系列专门为并发环境设计的集合类,如`ConcurrentHashMap`。 - **5.3 阻塞队列和生产者-消费者模式** ...
《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著。这本书深入浅出地探讨了Java平台上的多线程和并发编程,提供了丰富的...
- **线程安全类型**:Java提供了一些线程安全的集合类,如`Vector`、`Collections.synchronized*`方法包装的集合、`ConcurrentHashMap`等。 3. **同步机制** - **synchronized**:它可以保证同一时间只有一个线程...
- **简介**:Java SE 5引入了一组新的锁类,它们提供了比传统`synchronized`更灵活和更强大的功能。 - **示例**: - `ReentrantLock`:可重入锁,支持公平性和非公平性锁。 - `ReadWriteLock`:读写锁,允许多个读...
并发集合(Synchronized Collections)、并发集合(Concurrent Collections)、阻塞队列(Blocking Queues)以及生产者-消费者模式(Producer-Consumer Pattern)是构建并发程序的基石。 4. **同步器...
- **线程的创建**:Java提供了两种创建线程的方式,一是通过实现`Runnable`接口,二是继承`Thread`类。两者各有优缺点,前者更符合面向对象设计,后者可以直接调用`start()`方法执行。 - **线程的生命周期**:Java...
7. **多线程**:Java内置对多线程的支持,学习如何创建和管理线程,理解线程同步和互斥的概念,如synchronized关键字和wait/notify机制。 8. **反射与注解**:反射机制允许程序在运行时动态地获取类的信息并调用其...
9. **线程安全的类和方法**:Java API中有些类和方法被声明为线程安全,比如`Collections.synchronizedXXX`方法、`System.currentTimeMillis()`等。了解这些类和方法的特性,可以帮助我们避免不必要的同步。 10. **...
2.Collections: Collections 部分提供了一些并发集合类,例如 CopyOnWriteArrayList、ConcurrentHashMap 等,这些类可以在多线程环境下安全地使用。 3.Atomic: Atomic 部分提供了一些原子类,例如 ...
书籍如《Effective Java》、《Java Concurrency in Practice》和《Head First Java》等,都是学习Java高级编程的经典之作。在线资源如Oracle的Java Tutorials和Stack Overflow上的问答,为解决实际问题提供了大量...
Java并发编程是Java开发中的重要领域,而Java并发工具包(Java Concurrency Utility,简称JUC)则是Java标准库提供的一套强大而丰富的工具,它极大地简化了多线程环境下的编程工作。JUC主要包含在`java.util....
the Reflection API, String, StringBuffer, System, the Threading API, the collections framework, the concurrency utilities, the internationalization APIs, the Preferences API, Random, the Regular ...
10. **并行与并发(Concurrency)**:介绍Java中的线程和同步机制,如synchronized关键字、volatile变量和java.util.concurrent包。 11. **序列化(Serialization)**:解释如何实现Serializable接口,并探讨其潜在...
14. **并发编程(Concurrency)**:Java提供了丰富的并发工具类,如`ExecutorService`、`Semaphore`、`CountDownLatch`等,帮助开发者编写高效且线程安全的代码。 15. **JVM内存管理(JVM Memory Management)**:...