原创转载请注明出处:https://agilestyle.iteye.com/blog/2443652
CAS
CAS算法是乐观锁的一种实现方式,CAS算法中又涉及到自旋锁。
CAS是英文单词Compare and Swap(比较并交换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。
CAS算法涉及到三个操作数
1.需要读写的内存值 V2.进行比较的值 A
3.拟写入的新值 B
更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B,否则不会执行任何操作。一般情况下是一个自旋操作,即不断的重试。
自旋锁
自旋锁(spinlock):是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,”自旋”一词就是因此而得名。
Java实现自旋锁
package org.fool.hellojava.lock; import java.util.concurrent.atomic.AtomicReference; public class SpinLockTest { private static SpinLock lock = new SpinLock(); public static void main(String[] args) { new Thread(() -> { lock.lock(); test(); lock.unlock(); }).start(); new Thread(() -> { lock.lock(); test(); lock.unlock(); }).start(); new Thread(() -> { lock.lock(); test(); lock.unlock(); }).start(); } public static void test() { System.out.println(Thread.currentThread().getName() + " invoked test..."); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } private static class SpinLock { private AtomicReference<Thread> cas = new AtomicReference<>(); public void lock() { Thread currentThread = Thread.currentThread(); while (!cas.compareAndSet(null, currentThread)) { System.out.println(Thread.currentThread().getName() + " waiting..."); } } public void unlock() { Thread currentThread = Thread.currentThread(); cas.compareAndSet(currentThread, null); } } }
lock()方法利用的CAS,当第一个线程A获取锁的时候,能够成功获取到,不会进入while循环,如果此时线程A没有释放锁,另一个线程B又来获取锁,此时由于不满足CAS,所以就会进入while循环,不断判断是否满足CAS,直到A线程调用unlock方法释放了该锁。
自旋锁的缺点
1.如果某个线程持有锁的时间过长,就会导致其它等待获取锁的线程进入循环等待,消耗CPU。使用不当会造成CPU使用率极高。2.上面Java实现的自旋锁不是公平的,即无法满足等待时间最长的线程优先获取锁。不公平的锁就会存在“线程饥饿”问题。
相关推荐
自旋锁不会引起调用者睡眠,如果一个执行线程试图获得一个已经被持有的自旋锁,那么线程就会一直进行忙循环,一直等待下去,在那里看是否该自旋锁的保持者已经释放了锁,\"自旋\"一词就是因此而得名。由于自旋锁使用...
linux 自旋锁讨论记录,自旋锁与信号量有哪些差别,这里给出答案
信号量与自旋锁
根据《多处理器编程的艺术》一书第七章“自旋锁与争用”编写的C++代码,演示了10种锁的实现。代码为本人学习研究所用,欢迎高手赐教。
本文章是关于信号量、互斥体和自旋锁的区别。
纯英文,专门解析自旋锁起因及解决方法,SQL SERVER DBA必备
linux系统中基于自旋锁的进程调度的实现, 有代码和详细的文档说明,自旋锁(spinlock) 是用C和汇编指令实现的,有助于了解linux系统 内核的加锁机制。 很不错的哦。。。
基于SMP的Linux内核自旋锁分析.pdf
一种Linux内核自旋锁死锁检测机制的设计与实现.pdf
轻量级锁 “轻量级”是相对于使用操作系统互斥量来实现的传统锁而言的。但是,首先需要强调一点的是, 轻量级锁并不是用来代替重量级锁的,它的本意是在没有多线程竞争的前提下,减少传统的重量 级锁使用产生的...
线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享的临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。
对于互斥锁,如果资源已经被占用,自愿申请者只能进入睡眠状态。但自旋锁不会引起调用者睡眠
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中为了减少获得锁和释放...
Windows驱动编程视频教程 详尽的讲解 里面还有屏幕录制的录像
主要给大家介绍了关于我们说的CAS自旋锁到底是什么的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
自旋锁操作 spin_lock 这里给出了一个示例程序和编译方法,大家可以在运行中体验自旋锁的操作。 后续还有些函数的使用说明。
总结了 linux 设备驱动 自旋锁部分的思维导图
在多核操作系统环境下,同一时刻多任务同时访问内核,自旋锁可以很好地处理不同处理器之间存在的同步与互斥问题,但自旋锁如果使用不当,极易产生死锁,造成应用层功能无法实现,所以很有必要对自旋锁展开重点测试。...
并发控制之自旋锁.pdf
一、自旋锁 自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,即在标志寄存器中关闭/打开中断标志位,不需要...