标签:java 使用 io strong 数据 ar 问题 时间
在java5.0之前,在协调共享对象访问时可以使用的机制只有synchronized和volatile。java5.0增加了一种新的机制:ReentrantLock。ReentrantLock并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能。与内置锁不同的是Lock提供了一个无条件的、可轮询的、定时的以及可中断的锁获取操作,所有加锁和解锁都是显示的。在Lock的实现中必须提供与内部锁相同的内存可见性语义。
/**Lock接口*/ public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); }
ReetrantLock实现了一种标准的互斥锁:每次最多只有一个线程能持有ReetrantLock.对于维护数据完整性来说,互斥是一种过于强硬的加锁规则,因此也就不必要的限制了并发性。在许多情况下数据结构上的操作都是“读操作”。如果能够放宽加锁需求,允许多个执行读操作的线程同时访问数据结构,那么将提升程序的性能。只要每个线程都能确保读到最新的数据,并且在读取数据时不会有其它的线程修改数据,那么就不会发生问题。在这种情况下就可以使用读写锁:一个资源可以被多个读操作访问,或者被一个写操作访问,但是两者不能同时进行。
/*ReadWriteLock接口*/ public interface ReadWriteLock{ Lock readLock(); Lock writeLock(); }
在读锁和写锁之间的交互可以采用多种实现方式。ReadWriteLock中的一些可选实现包括:
ReentrantReadWriteLock为这两种锁都提供了可重入的语义。与ReentrantLock类似,ReentrantReadWriteLock在构造时也可以选择是一个非公平的锁(默认)还是一个公平的锁。在公平锁中,等待时间长的线程优先获得锁。如果这个锁由读线程持有,而另一线程请求写锁,那么其他线程不能获得读锁直到写锁被请求并使用后释放掉。在非公平的锁中,线程获得锁的顺序是不确定的。写线程降级为读线程是可以的,反过来不可以(会死锁的)。
与ReentrantLock类似的是,ReentrantReadWriteLock中的写入锁只能有一个持有者,并且只能有获得的线程释放。在Java5.0中的读锁更类似于Semaphore而不是锁,它只是维护活跃的读线程数量,而不考虑他们的标识,这样无法区别一个线程是是首次请求还是可重入请求,从而使公平的读写锁发生死锁。java6中修改了这个实现:记录哪些线程已经获得了读锁。
/*用读写锁来包装map*/ public class ReadWriteMap<K, V> { private final Map<K, V> map; private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Lock r = lock.readLock(); private final Lock w = lock.writeLock(); public ReadWriteMap(Map<K, V> map) { this.map = map; } public V put(K key, V value) { w.lock(); try { return map.put(key, value); } finally { w.unlock(); } } // 对remove(),putAll(),clear()等方法执行相同的操作 public V get(Object key) { r.lock(); try { return map.get(key); } finally { r.unlock(); } } // 对其它只读的map方法执行相同的操作 }
当锁的持有时间较长并且大部分是读操作时那么读写锁能很好的提高并发性。上面程序中使用了ReentrantReadWriteLock来包装Map,从而使它能够在多个读线程间被共享。在现实中ConcurrentHashMap的性能已经很好了,如果是需要一个并发的基于散列的映射,那么使用ConcurrentHashMap来代替这种方法。但如果需要对另一种Map实现(如LinkedHashMap)提供并发性更高的访问,那么可以使用这种技术。
参考:
- 现代操作系统
- Java并发编程实战
标签:java 使用 io strong 数据 ar 问题 时间
原文地址:http://blog.csdn.net/lgcssx/article/details/38615597