文章转载自http://www.importnew.com/22078.html

悲观锁和乐观锁

我们都知道,CPU是时分复用的,就是CPU把时间片,分配给不同的thread/process轮流执行,时间片与时间片之间,需要进行CPU切换,也就是会发生进程的切换。切换涉及到清空寄存器、缓存数据。然后重新加载新的thread所需数据。当一个线程被挂起时,加入到阻塞队列,在一定的时间或条件下,通过notify(),notifyAll()唤醒回来。在某个资源不可用的时候,就把CPU让出去,把当前的线程切换到阻塞状态。等到资源(如一个共享数据)可用了,就将线程唤醒,让他进入runnable状态等待CPU调度。这就是典型的悲观锁实现。独占锁是一种悲观锁,synchronized就是一种独占锁,他假设最坏的情况,并且只有在确保其他线程不会造成干扰的情况下执行,会导致其他所有需要锁的线程挂起,等待持有锁的线程释放锁。

但是,由于在进程挂起和恢复执行过程中存在着很大额开销。当一个线程正在等待锁时,他不能做任何事情,所有悲观锁有很大的缺点。举个例子,如果线程需要某个资源,但是资源的占用时间很短,当线程第一次抢占这个资源时,可能这个资源被占用,如果此时挂起这个线程,可能立刻就发现资源可用,然后有需要花费很长的时间重新抢占锁,时间代价就会非常的高。

所以就有的乐观锁的概念,他的核心思路就是:每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,知道成功为止。在上面的例子中,某个线程可以不让出CPU,而是一直WHILE循环,如果失败就重试,直到成功为止。所以,当数据争用不严重的时,乐观锁效果更好,比如CAS就是一种乐观锁思想的应用。

Java中CAS的实现

CAS就是Compare and Swap的意思,比较并操作。很多的CPU直接支持CAS指令。CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新一个变量时,只有其中一个线程能够更新变量的值,而其他线程都失败,失败的线程不会被挂起,而是被告知此次竞争失败,并可以再次尝试。CAS有3个操作数,内存值V,就的预期值A,要修改的新值B。当且仅当预期值A与内存值V相同时,将内存值修改为B,否则什么都不做。

JDK1.5中引人了底层的支持,在INT、long和对象的引用等类型上都公开的CAS操作,并且JVM把他们编译为底层硬件提供的最有效的方法,在运行CAS的平台上,运行时把他们编译为相应的机器指令。在java.util.concurrent.atmoic包下面所有的原子变量类型中,比如AtomicInteger,都使用了这些底层的JVM支持为数字类型的引用提供了一种高效的CAS操作。

在CAS操作中会出现ABA问题。就是如果V值现有A变B,再由B变A,那么仍然认为是发生了变化,并且需要重新执行算法中的步骤。有个简单的解决方案:不是更新某个引用的值,而是更新两个值,包括一个引用和一个版本号,即使这个值由A变B,然后变为A,版本号也是不同的。AtomicStampedReference和AtomicMarkableReference支持在两个变量上执行原子的条件更新。AtomicStampedReference更新一个“对象-引用”二元组,通过在引用上加上“版本号”,从而避免“ABA”问题,AtomicMarkableReference将更新一个“对象引用-布尔值”的二元组。

AtomicInteger的实现

AtomicInteger是一个支持原子操作的Integer类,就是保证AtomicInteger类型变量的增加和减少操作是原子性的,不会出现多个线程下数据不一致的问题。如果不使用AtomicInteger,要实现一个按顺序获取的ID,就必须在每次获取时进行加锁操作,以避免出现并发时获取到同样ID的现象。

编程语言java-并发(锁)的更多相关文章

  1. 深入理解 Java 并发锁

    本文以及示例源码已归档在 javacore 一.并发锁简介 确保线程安全最常见的做法是利用锁机制(Lock.sychronized)来对共享数据做互斥同步,这样在同一个时刻,只有一个线程可以执行某个方 ...

  2. Java 并发锁

    Java 中的锁 阻塞锁.可重入锁.读写锁.互斥锁.悲观锁.乐观锁.公平锁.偏向锁.对象锁.线程锁.锁粗化.锁消除.轻量级锁.重量级锁.信号量.独享锁.共享锁.分段锁 一.常见的锁 synchroni ...

  3. java并发锁ReentrantReadWriteLock读写锁源码分析

    1.ReentrantReadWriterLock 基础 所谓读写锁,是对访问资源共享锁和排斥锁,一般的重入性语义为如果对资源加了写锁,其他线程无法再获得写锁与读锁,但是持有写锁的线程,可以对资源加读 ...

  4. 如何理解Java中眼花缭乱的各种并发锁?

    在互联网公司面试中,很多小伙伴都被问到过关于锁的问题. 今天,我给大家一次性把Java并发锁的全家桶彻底讲明白.包括互斥锁.读写锁.重入锁.公平锁.悲观锁.自旋锁.偏向锁等等等等.视频有点长,大家一定 ...

  5. 百万并发中间件系统的内核设计看Java并发性能优化

    “ 这篇文章,给大家聊聊一个百万级并发的中间件系统的内核代码里的锁性能优化. 很多同学都对Java并发编程很感兴趣,学习了很多相关的技术和知识.比如volatile.Atomic.synchroniz ...

  6. 深入并发锁,解析Synchronized锁升级

    这篇文章分为六个部分,不同特性的锁分类,并发锁的不同设计,Synchronized中的锁升级,ReentrantLock和ReadWriteLock的应用,帮助你梳理 Java 并发锁及相关的操作. ...

  7. Java 并发机制底层实现 —— volatile 原理、synchronize 锁优化机制

    本书部分摘自<Java 并发编程的艺术> 概述 相信大家都很熟悉如何使用 Java 编写处理并发的代码,也知道 Java 代码在编译后变成 Class 字节码,字节码被类加载器加载到 JV ...

  8. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  9. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  10. 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

    img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...

随机推荐

  1. 查询数组里有多少个数在[L,R]范围中(二分)

    使用两次二分即可得到这个值 比如现在有一个vector<int> vec,里面存放的是有序数列. 我们现在希望找出范围在[L,R]之间的数有多少个. 则有cnt = upper_bound ...

  2. 最牛B的编码套路

    最近,我大量阅读了Steve Yegge的文章.其中有一篇叫“Practicing Programming”(练习编程),写成于2005年,读后令我惊讶不已:   与你所相信的恰恰相反,单纯地每天埋头 ...

  3. 23. Sum Root to Leaf Numbers

    Sum Root to Leaf Numbers Given a binary tree containing digits from 0-9 only, each root-to-leaf path ...

  4. 解决eclipse中安装AIX2插件问题

    为了做webservice,查了下,需要用到AXIS2(当然也有别的方法,貌似更复杂,详情可以参看:java开发webservice的几种方式).可试了N次,下载的codegen和service插件始 ...

  5. 七、context command

    context command是用来新建自己的工具,可以调用OPENGL,获取鼠标操作函数,在view窗口画自己想画的东西.(我是这麽理解的,可以以后再确定一下) 下面是一个context comma ...

  6. C#开发Windows服务 附简单实例实现禁止QQ运行

    本实例主要实现下面三个基本功能 1.C#开发windows服务 2.禁止QQ等程序运行 3.为windows服务创建自动安装程序 下面针对这三个基本功能进行实现 一.C#开发windows服务 Win ...

  7. 2016-08-15: C++ traits

    #include <stdio.h> template <typename T> struct TraitsHelper { static const bool isPoint ...

  8. jexus

    Jexus web server V5.1 安装配置要点 一.Jexus简介:Jexus web server for linux 是一款基于.NET兼容环境,运行于Linux/unix操作系统之上, ...

  9. Qlikview 的服务器

    服务器管理 1 , Create a job 1.1 转到 Documents 分页 1.2 从左边目录搜索到 需要执行Job的qvw报表,如 "getting start.qvw" ...

  10. KMeans的图像压缩

    # -*- coding: utf-8 -*- """ Created on Thu Aug 11 18:54:12 2016 @author: Administrato ...