5

基于CAS实现的锁

 2 years ago
source link: https://allenwind.github.io/blog/4161/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Mr.Feng Blog

NLP、深度学习、机器学习、Python、Go

基于CAS实现的锁

好久没有更新博客了,这两个月发生的几件事情耽误了很多计划,现在总算慢慢步入正轨…今天写写平时在并发编程中使用锁的实现原理。本文以Java和Go语言为例。

Java和Go语言中的锁都是基于CAS实现,CAS就是比较和交换(Compare And Set)这是一个原子过程,需要硬件层面提供支持,在汇编上涉及核锁。

Java中java.util.concurrent.locks包中的锁的实现方式都是基于CAS。CAS的相关操作由操作系统提供相关的接口,在Java中,它们封装在java.util.concurrent.atomic上。

下面实现一个简单的锁

import java.util.concurrent.atomic.AtomicInteger;

public class SimpleLock {
private AtomicInteger status = new AtomicInteger(0);

public void lock() {
while(!status.compareAndSet(0, 1)) {
return
}
}

public void unlock() {
status.compareAndSet(1, 0);
}
}

代码中,0表示锁没有被获取,1表示锁已经被一个线程占有。获取锁时,会原子地把status从0设置为1,然后返回,让线程继续执行其代码,如果status已经为1,那么获取锁的线程一直循环地尝试获取锁,而不是加入锁等待队列。

这个示例反映了锁的最核心实现,它还需要很多改进。比如,解决ABA问题,读写分离的锁,饥饿问题。

下面给出Go语言的实现,原理上一样,语法层面也相似。

package main

import (
"sync/atomic"
)

type Mutex struct {
state int32
}

func (m *Mutex) Lock() {
for(!atomic.CompareAndSwapInt32(&m.state, 0, 1)) {
return
}
}

func (m *Mutex) Unlock() {
atomic.CompareAndSwapInt32(&m.state, 1, 0)
}

完善锁的功能,包括饥饿处理,超时控制,spin,线程等待队列,公平性…这样我们就有了一把基于CAS完整的锁了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK