我们知道一个线程在尝试获取锁失败后将被阻塞并加入等待队列中,它是一个怎样的队列?又是如何管理此队列?这节聊聊CHL Node FIFO队列。
 在谈到CHL Node FIFO队列之前,我们先分析这种队列的几个要素。首先要了解的是自旋锁,所谓自旋锁即是某一线程去尝试获取某个锁时,如果该锁已经被其他线程占用的话,此线程将不断循环检查该锁是否被释放,而不是让此线程挂起或睡眠。它属于为了保证共享资源而提出的一种锁机制,与互斥锁类似,保证了公共资源在任意时刻最多只能由一条线程获取使用,不同的是互斥锁在获取锁失败后将进入睡眠或阻塞状态。下面利用代码实现一个简单的自旋锁,
public class SpinLock {
private static Unsafe unsafe = null;
private static final long valueOffset;
private volatile int value = 0;
static {
try {
unsafe=getUnsafeInstance();
valueOffset = unsafe.objectFieldOffset(SpinLock.class
.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
private static Unsafe getUnsafeInstance() throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
public void lock() {
for (;;) {

int newV = value + 1;

if(newV==1)

if (unsafe.compareAndSwapInt(this, valueOffset, 0, newV)){
                return ;
                }
        }
}
public void unlock() {
unsafe.compareAndSwapInt(this, valueOffset, 1, 0);
}
}
这是一个很简单的自旋锁,主要看加粗加红的两个方法lock和unlock,Unsafe仅仅是为操作提供了硬件级别的原子CAS操作,暂时忽略此类,只要知道它的作用即可,我们将在后面的“原子性如何保证”小节中对此进行更加深入的阐述。对于lock方法,假如有若干线程竞争,能成功通过CAS操作修改value值为newV的线程即是成功获取锁的线程,将直接通过,而其他的线程则不断在循环检测value值是否又改回0,而将value改为0的操作就是获取锁的线程执行完后对该锁进行释放,通过unlock方法释放锁,释放后若干线程又对该锁竞争。如此一来,没获取的锁也不会被挂起或阻塞,而是不断循环检查状态。图2-5-9-3可加深自旋锁的理解,五条线程轮询value变量,t1获取成功后将value置为1,此状态时其他线程无法竞争锁,t1使用完锁后将value置为0,剩下的线程继续竞争锁,以此类推。这样就保证了某个区域块的线程安全性。
 
图2-5-9-3 自旋锁

自旋锁适用于锁占用时间短,即锁保护临界区很小的情景,同时它需要硬件级别操作,也要保证各缓存数据的一致性,另外,无法保证公平性,不保证先到先获得,可能造成线程饥饿。在多处理器机器上,每个线程对应的处理器都对同一个变量进行读写,而每次读写操作都将要同步每个处理器缓存,导致系统性能严重下降。

喜欢研究java的同学可以交个朋友,下面是本人的微信号:

Java并发框架——AQS阻塞队列管理(一)——自旋锁的更多相关文章

  1. Java并发框架——AQS阻塞队列管理(三)——CLH锁改造

    在CLH锁核心思想的影响下,Java并发包的基础框架AQS以CLH锁作为基础而设计,其中主要是考虑到CLH锁更容易实现取消与超时功能.比起原来的CLH锁已经做了很大的改造,主要从两方面进行了改造:节点 ...

  2. Java并发框架——AQS阻塞队列管理(二)——自旋锁优化

    看Craig, Landin, and Hagersten发明的CLH锁如何优化同步带来的花销,其核心思想是:通过一定手段将所有线程对某一共享变量轮询竞争转化为一个线程队列且队列中的线程各自轮询自己的 ...

  3. Java并发框架——AQS堵塞队列管理(一)——自旋锁

    我们知道一个线程在尝试获取锁失败后将被堵塞并增加等待队列中,它是一个如何的队列?又是如何管理此队列?这节聊聊CHL Node FIFO队列.  在谈到CHL Node FIFO队列之前,我们先分析这样 ...

  4. 深入理解Java并发框架AQS系列(一):线程

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.概述 1.1.前言 重剑无锋,大巧不工 读j.u.c包下的源码,永远无法绕开的经典 ...

  5. 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.AQS框架简介 AQS诞生于Jdk1.5,在当时低效且功能单一的synchroni ...

  6. 深入理解Java并发框架AQS系列(四):共享锁(Shared Lock)

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 深入理解Java并发框架AQS系列(三):独占锁(Exclusive Lock) 深入 ...

  7. Java并发编程:阻塞队列(转载)

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  8. 【转】Java并发编程:阻塞队列

    在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程 ...

  9. 12、Java并发编程:阻塞队列

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

随机推荐

  1. ●BZOJ 3796 Mushroom追妹纸

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3796 题解: 题意:    给出三个串 A,B,C    找出一个最长串 S,    使得 ...

  2. [BZOJ]1045 圆上的整点(HAOI2008)

    数学题第二弹! Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. Input 一个正整数r. Output 整点个数. Sample Input 4 ...

  3. java随机生成字符串和校验

    首先定义字符串 String a = "0123456789"; // 数字 String b = "abcdefghijklmnopqrstuvwxyz"; ...

  4. Linux 基本bash命令

    1.查看文件大小.内存大小.cpu信息.硬盘空间 显示当前目录所有文件大小的命令:ls -lht 内存空间.CPU信息.硬盘空间:htop.top(htop详解参考:http://blog.csdn. ...

  5. Windows 2008 R2_NLB网络负载均衡(图文详解)(转)

    目录 前言 软件环境 DNS域名服务器 DNS服务器原理 DNS域名空间 DNS区域 DNS服务器的类别 DNS查询模式 缓存文件 配置DNS服务器 DNS服务的应用 新建子域 在DNS正向解析中新建 ...

  6. 使用pscp实现Windows 和 Linux 服务器间的远程拷贝文件

    在工作中,每次部署应用时都需要从本机Windows 服务器拷贝文件到Linux 上,有时还将Linux 上的文件拷到本机,这些操作都是可以使用pscp实现的.下文将详细描述如何使用: PSCP (Pu ...

  7. Head First Java设计模式思维导图总结

    关于Head First Java设计模式的思维导图总结:

  8. C++ 实现俄罗斯方块

    C++ 实现俄罗斯方块 一.实验介绍 1.1 实验内容 本节实验我们进行设计俄罗斯方块前的思路分析,以及介绍ncurses 库的使用方法. 1.2 实验知识点 C++ 编程基础 ncurses 库的使 ...

  9. 有趣的冷知识:编程中Foo, Bar 到底什么意思?

    转自:编程中Foo, Bar 到底什么意思? 1 前言 在很多国外计算机书本和一些第三份开源软件的Demo中经常用到两个英文单词Foo,Bar.这到底是什么意思呢?从步入屌丝界的IT生活见到这两个单词 ...

  10. kafka Centos7.2 单机集群搭建

    前提是已经安装好了zk集群 1.下载  kafka_2.11-1.0.0.tgz  下载网址 http://kafka.apache.org/documentation.html 2.解压  tar ...