非阻塞算法的关键思想就是CAS,CAS是compare and set的缩写,也常被称为lock-free或者wait-free,通过把compare和set两个操作原子化,使得不需要使用锁,但是能够解决并发中的资源争用问题。由于CAS常常是一个回退算法+死循环,所以又被称为spin-lock。由于CAS没有使用锁,线程持续执行,又称为非阻塞算法(non-blocking)。术语不统一,但是都差不多表示同一个东西,我都列在这里,方便初学者理解。
CAS通常并发性能会更好,原因有二:
1、CAS由硬件提供指令支持
2、整个思路属于乐观锁定,而不同于其他类型的锁所采用的悲观锁定,大多数并发程序,冲突发生时间较少,所以乐观锁定更高效。
非阻塞算法是当前的一个研究热点,也越来流行。其显著的优势在于避免了锁带来的问题,而其主要缺点在于与等价的有锁算法比较而言,非阻塞算法的实现要复杂一些。在Java中,doug lea为我们带来util.concurrent包,CAS在整个并发框架中深入应用,不单提高了效率(atomic),而且提高了接口可用性(例如CurrentMap的putIfAbsent)。
有人说,CAS这种技术底层框架提供,不需要了解,其实不然,CAS思想可以应用任何地方,包括数据结构、服务接口、数据库应用等等。我这篇文章要讲的内容就是在关系数据库应用中使用CAS思想。
闲话少说,言归正传!
关系数据库数据库提供了"update T set FState = xx where FState = xx",执行这样的SQL,会返回一个更新行数,在jdbc或者odbc或者ADO .NET中都可以获得更新行数。上面的SQL,如果更新行数>0,则是更新成功,否则是没有进行任何更新,这是很典型的CAS。可以说,关系数据库原生支持CAS。
例如,现在有一个表:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->Create Table T_COUNTER (FName VARCHAR, FCOUNT INT)
这个表存储一些计数器,程序需要对其中的一个计数器进行getAndIncrement的操作,实现如下:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->// incremnt的实现算法在这个方法里
// 三点:外部循环、成功执行操作则退出循环、不成功则重来
public int getAndIncrement(String name) {
for (;;) {
int expectValue = getCurrentValue(name);
int updateValue = expectValue + 1;
if (updateCounter(name, expectValue, updateValue)) return expectValue;
}
}
public boolean updateCounter(String name, int expectValue, int updateValue) {
String sql = "UPDATE T_COUNTER SET FCOUNT = @updateValue WHERE FName = @name AND FCOUNT = @expectValue";
int updateCount = executeUpdate(sql);
return updateCount > 0;
}
public int getCurrentValue(String name) {
// SELECT FCOUNT FROM T_COUNTER WHERE FNAME = @name
// TODO 执行这段SQL,返回FCOUNT的值
return 0;
}
private int executeUpdate(String sql) {
// TODO 执行SQL,返回更新行数
return 0;
}
这样的实现,避免SQL Server中使用locking hints,Oracle、DB2、MySQL中使用select for update长时间锁定T_COUNTER表,性能更好,也更通用。要知道使用locking hints,不同厂商的数据库的实现是不一样的,Oracle和Microsoft SQL Server就相差很大。
这样做的优点:
1、性能更好
2、锁表时间更短
3、基于标准SQL,不同的关系数据库通用
4、上述实现并不复杂
分享到:
相关推荐
- **Memcached**:内存键值存储系统,常用于缓存数据库查询,提高Web应用程序性能。 - **Hadoop HBase**:基于Hadoop的分布式列存储数据库,适用于大数据场景。 - **Cassandra**:Facebook开发的分布式数据库,...
- 注解映射:在实体类的Java代码中使用注解进行映射。 **四、Hibernate主键生成方式** 4.1 五种生成方式 - assigned:由应用手动指定。 - identity:数据库自增,如MySQL的 AUTO_INCREMENT。 - sequence:使用...
7. **异步编程**:C#支持异步编程模型,使用async和await关键字可以编写非阻塞的代码,提高程序的响应性和性能。 8. **.NET框架与.NET Core**:C#与.NET框架紧密关联,但随着.NET Core的出现,C#也支持跨平台开发。...
异步编程在现代软件开发中至关重要,特别是在处理I/O密集型任务或网络操作时。C#通过async/await关键字实现了异步编程模型,使得编写非阻塞代码变得简单。这种方式可以避免程序在等待资源时陷入阻塞,提高应用程序的...
它使用事件驱动、非阻塞I/O模型,使其轻量又高效,非常适合数据密集型实时应用。 - **关键技术点**: - 了解事件循环机制; - 掌握异步编程方法,如Promise、async/await等; - 使用Express框架快速构建Web...
《C#编程思想》是一本深入探讨C#编程精髓的教程,它旨在帮助读者理解C#语言的核心概念、设计哲学以及在实际开发中的应用策略。本教程覆盖了C#的各个方面,从基础语法到高级特性,包括面向对象编程、泛型、LINQ、异步...
MySQL是一种关系型数据库管理系统,因其速度快、易于安装等特点,在Web应用开发中被广泛应用。在本项目中,MySQL用于存储用户的个人信息、发布的文章等内容。 ##### 2.4 后端框架——Express Express是基于Node.js...
C#是Microsoft开发的一种面向对象的编程语言,广泛应用于构建Windows桌面应用程序、Web应用程序以及游戏开发等领域,尤其是与.NET Framework和.NET Core平台相结合时,其强大功能得以充分展现。 C#的关键特性包括:...
Java EE则主要用于开发Web应用程序和服务端应用程序;Java ME则针对嵌入式设备和移动设备。 #### 1.4 Java SE环境安装和配置 安装Java SE环境首先需要下载JDK(Java Development Kit),然后根据操作系统类型进行...
随着信息技术的发展,面向对象已经成为现代软件开发中不可或缺的思想方法。它强调通过抽象、封装、继承和多态等机制来构建复杂系统模型。在软考中可能会涉及面向对象的基本概念及其在特定语言中的实现方式等问题。 ...
5. **IO流**:Java的输入/输出系统包括字符流和字节流,以及NIO(非阻塞I/O)和File类等,用于数据的读写操作。 6. **网络编程**:Socket编程是Java进行网络通信的基础,可以实现客户端-服务器模型的应用。 7. **...
- **Java EE**(Enterprise Edition):企业版,用于开发Web应用程序和企业级应用程序。 - **Java ME**(Micro Edition):微型版,用于开发移动设备和嵌入式设备的应用程序。 #### 1.4 Java SE环境安装和配置 ...
对于网络编程,Java的Socket API和NIO(非阻塞I/O)框架使得Java工程师能够创建高性能的网络应用。数据库交互则可以通过JDBC进行,而ORM(对象关系映射)框架如Hibernate则简化了这一过程。书中将介绍如何使用这些...
1. **React**:React是Facebook开发的一个用于构建用户界面的JavaScript库,尤其适合开发单页应用程序。在本项目中,React负责构建动态、交互性强的新闻展示和推荐页面。它使用组件化思想,让开发者可以将UI拆分为...
- **高性能**:通过非阻塞I/O和事件驱动模型实现。 - **灵活性**:支持TCP、UDP等多种协议。 - **应用场景**:适合用于构建各种高性能网络应用,如游戏服务器、聊天服务器等。 ##### 2.10 AWS EBS采用的SNAPSHOT...
- **非阻塞I/O**:使用非阻塞I/O模型,当请求等待时不会消耗CPU资源。 4. **协议与命令** - **简单文本协议**:Memcached使用基于行的文本协议,易于实现和理解,支持命令如GET、SET、ADD、DELETE等。 - **命令...