如果有一个资料档有可能同时间会有许多客户端对它进行读取与写入的动作,则必须注意资料的同步问题,像是两个写入者进行写入时,后一个写入者的资料会有可能将次一个写入者的资料覆盖掉;而有时您希望读取者看到的是最新的资料,如果在读取的时候,有写入者想要对资料进行写入,则最好等待读取者读取完毕,相反的如果在写入时有客户想要读取资料,则最好等待,以确保读出来的资料是最新的资料。
读取写入的同步问题向来是难解的问题之一,有几个可行的作法,例如若有写入的动作时,则读取者以唯读模式开启;或是如果有开启资料档的动作时,无论是读取或是写入,后一个开启档案的客户都一律以唯读模式开启;还有最干脆的作法,就是将这个问题由客户决定,在开启档案时若已有其他人开启中,则提供选项让客户决定要不要以唯读模式开启,通常这个作法是提供给档案的拥有者使用。
Read-Write-Lock 模式提供给被读取或写入的资料“一把锁”,在读取或写入时都必须先取得这把锁,读取的客户可以同时共同这把锁,而写入的客户也可以共用这把锁,但读取不可与写入共用一把锁,如果尝试取得锁时发现锁已经被另一方取得,则等待直到锁被释放并重新取得它。
下图读取者读取资料时的Sequence Diagram示例:
现在假设读取者已经取得锁,而写入者试图进行写入,它也试图先取得锁定,但发现锁已经被读取的一方拥有,于是先进入等待,直到读取的一方解除锁定为止:
一个简单的Java程式例子如下所示:
public void readData() {
lock.readLock();
doRead();
lock.readUnLock();
}
public void writeData() {
lock.writeLock();
doWrite();
lock.writeUnLock();
}
而最主要的关键还是在于锁的实现,在Java中可以用wait()、notify()来实现,实现的片段如下:
private boolean writerFirst = true; // 写入优先
public synchronized void readLock() {
try {
while(writingWriters > 0 ||
(writerFirst && waitingWriters > 0)) {
wait();
}
}
catch(InterruptedException) {
}
readingReaders++;
}
public synchronized void readUnLock() {
readingReaders--;
writerFirst = true;
notifyAll();
}
public synchronized void writeLock() {
waitingWriters++
try {
while(readingReaders > 0 || writingWriters > 0) {
wait();
}
}
catch(InterruptedException) {
}
finally {
waitingWriters--;
}
writingWriters++;
}
public synchronized void writeUnLock() {
writingWriters--;
writerFirst = false;
notifyAll();
}
其中writerFirst是写入优先的旗标,它确保只要有写入的执行绪在等待时,在解除锁定的时候,可以优先由写入执行绪取得锁定,以确保读取者读取到的资料可以是最新的,但缺点就是写入的动作很频繁时,读取者必须等待的机会将增多,相反的若设定为读取优先,则读取时的回应性会增高,但资料更新的速率将会下降,实际使用时要偏好哪一方,必须视应用的场合而定。
ReadWriteLock
public interface ReadWriteLockReadWriteLock 维护了一对相关的锁定,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁定可以由多个 reader 线程同时保持。写如锁定是独占的。
与互斥锁定相比,读-写锁定允许对共享数据进行更高级别的并发访问。虽然一次只有一个线程(writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程可以同时读取共享数据(reader 线程),读-写锁定利用了这一点。从理论上讲,与互斥锁定相比,使用读-写锁定所允许的并发性增强将带来更大的性能提高。在实践中,只有在多处理器上并且只在访问模式适用于共享数据时,才能完全实现并发性增强。
与互斥锁定相比,使用读-写锁定能否提升性能则取决于读写操作期间读取数据相对于修改数据的频率,以及数据的争用——即在同一时间试图对该数据执行读取或写入操作的线程数。例如,某个最初用数据填充并且之后不经常对其进行修改的 collection,因为经常对其进行搜索(比如搜索某种目录),所以这样的 collection 是使用读-写锁定的理想候选者。但是,如果数据更新变得频繁,数据在大部分时间都被独占锁定,这时,就算存在并发性增强,也是微不足道的。更进一步地说,如果读取操作所用时间太短,则读-写锁定实现(它本身就比互斥锁定复杂)的开销将成为主要的执行成本,在许多读-写锁定实现仍然通过一小段代码将所有线程序列化时更是如此。最终,只有通过分析和测量,才能确定应用程序是否适合使用读-写锁定。
尽管读-写锁定的基本操作是直截了当的,但实现仍然必须作出许多决策,这些决策可能会影响给定应用程序中读-写锁定的效果。这些策略的例子包括:
在 writer 释放写入锁定时,reader 和 writer 都处于等待状态,在这时要确定是授予读取锁定还是授予写入锁定。Writer 优先比较普遍,因为预期写入所需的时间较短并且不那么频繁。Reader 优先不太普遍,因为如果 reader 正如预期的那样频繁和持久,那么它将导致对于写入操作来说较长的时延。公平或者“按次序”实现也是有可能的。
在 reader 处于活动状态而 writer 处于等待状态时,确定是否向请求读取锁定的 reader 授予读取锁定。Reader 优先会无限期地延迟 writer,而 writer 优先会减少可能的并发。
确定是否重新进入锁定:可以使用带有写入锁定的线程重新获取它吗?可以在保持写入锁定的同时获取读取锁定吗?可以重新进入写入锁定本身吗?
可以将写入锁定在不允许其他 writer 干涉的情况下降级为读取锁定吗?可以优先于其他等待的 reader 或 writer 将读取锁定升级为写入锁定吗?
当评估给定实现是否适合您的应用程序时,应该考虑所有这些情况。
分享到:
相关推荐
Analog Circuit Design: High-speed Clock and Data Recovery, High-performance Amplifiers, Power Management By Michiel Steyaert, Arthur H.M. van Roermund, Herman Casier Publisher: Springer Number Of ...
ASP.NET 2.0 Website Programming: Problem - Design - Solution 第二部分 Table of Contents ASP.NET 2.0 Website Programming—Problem - Design - Solution Foreword Introduction ...
FOAD(Fundamentals of Object-Oriented Design)设计模式,是对面向对象设计原则的具体实现,旨在提高代码的可读性、可维护性和可扩展性。在C#编程语言中,这些模式被广泛运用,以优化程序结构,提高代码质量。 1....
"Design pattern In JavaScript"这个主题涵盖了一系列广泛使用的模式,这些模式可以分为三大类:创建型、结构型和行为型。 1. **创建型模式**: - **工厂模式**:它提供了一种创建对象的接口,但允许子类决定实例...
Networkers2009:BRKCAM-3011 - Advanced Enterprise Campus Design: Leveraging Virtual Switch System
The text enables students to do SAD—not just read about it, but understand the issues so they can actually analyze and design systems. The text introduces each major technique, explains what it is, ...
本文档可以解决win10环境中使用ISE14.7的Simulation仿真时总是出错"ERROR:Simulator:861 – Failed to link the design" 解决方法和解决工具都在本文档里面!下载查看。
这个名为"java-design-pattern"的压缩包很可能是包含了一系列Java实现的设计模式示例代码库。下面,我们将深入探讨Java设计模式的重要性和各种类型。 设计模式是经过多年实践和经验总结出的通用解决方案,它们描述...
在这个项目中,“javascript-design-pattern”显然是一个专注于前端设计模式的学习资源,通过示例(demo)来帮助开发者理解和应用这些模式。 首先,我们要了解设计模式的基本概念。设计模式是经过多次实际开发经验...
在给定的标题“design-pattern-factory-method:Código-exemplopara ilustrar o Padrão de Projeto Factory Method”中,我们关注的是工厂方法(Factory Method)设计模式。这是一种创建型设计模式,它定义了一个...
英文原书名: Design Patterns:Elements of Reusable Object-Oriented software 作者: Erich Gamma 等 译者: 李英军 马晓星 蔡敏 刘建中 书号: 7-111-07575-7 页码: 254 定价: ¥35.00 会员价: ¥31.50 币值: 315 ...
设计模式:可复用面向对象软件的基础(中文)Design Patterns:Elements of Reusable Object-Oriented software
Aspect-oriented software design (ASOD), which follows the Java philosophy of "write once, run anywhere", is a new way of thinking about program construction. It is a rapidly growing and evolving ...
Wiley出版:TCP-IP Architecture Design and Implementation in Linux(2008).pdf 共6个部分。我都上传了,搜索这个标题就能找到。
"DesignPattern-321: 参考-头先设计模式"这个项目可能是一个关于设计模式的学习资源,其中包含了对策略模式的应用以及对继承与组合的讨论。下面将详细解析这些知识点。 **策略模式**是一种行为设计模式,它使你能在...
信号与系统教学课件:9-3 Design for LTI systems.ppt
信号与系统教学课件:9-5 Design for LTI systems.ppt
信号与系统教学课件:10-3 Design for LTI systems.ppt