惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Know Your Adversary
Know Your Adversary
小众软件
小众软件
L
LangChain Blog
月光博客
月光博客
博客园 - Franky
Microsoft Azure Blog
Microsoft Azure Blog
Y
Y Combinator Blog
有赞技术团队
有赞技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MongoDB | Blog
MongoDB | Blog
Recorded Future
Recorded Future
V
Visual Studio Blog
TaoSecurity Blog
TaoSecurity Blog
S
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
L
LINUX DO - 热门话题
C
Check Point Blog
F
Fortinet All Blogs
Hugging Face - Blog
Hugging Face - Blog
The Hacker News
The Hacker News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Security Blog
Microsoft Security Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
博客园 - 司徒正美
T
Threatpost
P
Palo Alto Networks Blog
A
About on SuperTechFans
Spread Privacy
Spread Privacy
Engineering at Meta
Engineering at Meta
N
News | PayPal Newsroom
T
Tailwind CSS Blog
The Last Watchdog
The Last Watchdog
Blog — PlanetScale
Blog — PlanetScale
A
Arctic Wolf
量子位
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 聂微东
Google Online Security Blog
Google Online Security Blog
Google DeepMind News
Google DeepMind News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
Vulnerabilities – Threatpost
H
Hacker News: Front Page

博客园 - 李潘

我们为什么需要分布式系统? 怎么算是在工作中负责? 怎么更好的沟通? 怎么用工作邮件? 为工作排好优先级 聊聊数据压缩 怎么正确使用锁? 聊聊缓存 为什么Kafka的性能那么好? 怎么避免服务内存溢出? 应用程序之间的通信传输协议 怎么选择数据序列化方案? 怎么利用异步设计提升系统性能? 怎么处理消息积压问题? 怎么处理消息重发的问题? 怎么做才能不丢消息? 怎么用消息队列实现分布式事务? 聊聊消息队列中的基础概念 我们要选择哪个消息队列产品?
怎么使用硬件同步原语替代锁?
李潘 · 2023-03-19 · via 博客园 - 李潘

什么是硬件同步原语?

硬件同步原语(Atomic Hardware Primitives)是由计算机硬件提供的一组原子操作。

我们常见的原语操作有CAS和FAA两种。

CAS

Compare and Swap(CAS),字面意思是先比较,再计算。它的伪代码如下。

<< atomic >>
function cas(p : pointer to int, old : int, new : int) returns bool {
    if *p ≠ old {
        return false
    }
    *p ← new
    return true
}

它的输入参数有三个:

  • p:要修改的变量的指针
  • old:旧值
  • new:新值

返回值是一个布尔值,标识是否赋值成功。

FAA

Fetch and Add(FAA),它的含义是先获取变量当前的值value,然后给变量p增加inc,最后返回变量p之前的值value。

它的伪代码如下:

<< atomic >>
function faa(p : pointer to int, inc : int) returns int {
    int value <- *location
    *p <- value + inc
    return value
}

上述两段伪代码,它们的特殊之处在于它们都是由计算机硬件,具体讲就是CPU提供实现,可以保证操作的原子性。

因为原子操作具有不可分割性,也就不存在并发的问题,所以在某些情况下,原语可以用来替代锁,实现一些安全又高效的并发操作。

CAS和FAA在各种编程语言中,都有相应的实现,可以直接使用,无论哪种编程语言,它们底层的实现是一样的,效果也是一样的。

Java中的操作原语

Java语言本身支持操作原语,Java中的CAS可以理解为乐观锁,java.util.concurrent.atomic包下面的类已经实现了乐观锁,其中最常用的是AtomicInteger,可以将其看做实现了CAS操作的Integer。

下面是使用AtomicInteger的示例代码。

    private static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) {
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //每个线程让count自增100次
                    for (int i = 0; i < 100; i++) {
                        count.incrementAndGet();
                    }
                }
            }).start();
        }

        try{
            Thread.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(count);
    }