目录

一、整数类型的原子操作

二、布尔类型的原子类型

三、引用类型的原子操作

四、小结


原子操作是指在多线程中的一个不可分割的操作单元。在一个原子操作中,要么所有步骤都执行,要么所有操作都不执行。比如:在进行转账的时候,甲向乙转账100元,就是甲的钱减少100元,乙的钱多100元,如果因为某种原因而导致转账失败,那么整个操作都要回滚,否则就会导致数据不一致。

原子操作的时候需要导包

import std.sync.*

一、整数类型的原子操作

整数类型原子操作支持基本的读写、交换以及算数运算符操作。

package Study
// 导包
import std.sync.*
import std.collection.*
 
let counter = AtomicInt64(100)
 
main () {
    let futures = ArrayList<Future<Int64>>()
 
    // 创建100个子线程
    for (_ in 0..100) {
        let future = spawn {
            // 在每个子线程中增加,这里是原子操作
            counter.fetchAdd(1)
        }
        // 将子线程对应的Future实例添加到futures中
        futures.add(future)
    }
 
    // 等待所有子线程执行结束
    for (future in futures) {
        // 阻塞主线程,直到future对应的子线程执行结束
        future.get()
    }
 
    println(counter.load())
}

二、布尔类型的原子类型

布尔类型的原子操作支持基本的读写、交换操作。

package Study
// 导包
import std.sync.*
import std.time.*
import std.random.Random
import std.collection.*

// 标记电话是否正在接听,初始不接听
let isCalling = AtomicBool(false)

func callControl() {
    // 如果电话正在接听,则输出信息
    if (isCalling.load()) {
        println("线程${Thread.currentThread.id} 正在等待接听")
    }

    // 当前线程在接听空闲时接听
    while (true) {
        // 在设置接听标记为true后,开始接听
        if (isCalling.compareAndSwap(false, true)) {
            println("线程${Thread.currentThread.id} 正在接听")
            // 模拟通话时间
            sleep(Duration.millisecond * Random().nextInt64(5000))
            println("线程${Thread.currentThread.id} 接听结束")
            // 设置接通为false
            isCalling.store(false)
            break
        }
    }
}

main () {
    // 创建一个list存储所有子线程实例
    let list = ArrayList<Future<Unit>>()

    // 创建5个电话子线程
    for (_ in 0..5) {
        let future = spawn {
            callControl()
        }
        // 将子线程对应的Future实例添加到list
        list.add(future)
    }

    // 等待所有子线程执行结束
    for (future in list) {
        // 阻塞主线程,直到子线程执行结束
        future.get()
    }
    println("所有通话结束")
}

三、引用类型的原子操作

引用类型的原子操作支持基本的读写、交换操作。

package Study
// 导包
import std.sync.*
import std.collection.*

// 使用AtomicReference安全处理缓存对象
let cache = AtomicReference(CacheObject(""))

// 模拟缓存对象
class CacheObject {
    CacheObject(var data: String){}
}

/*
* 更新缓存信息
*/
func updateCache(data: String) {
    while (true) {
        let expectedCache = cache.load()
        let newChcae = CacheObject(data)
        if (cache.compareAndSwap(expectedCache, newChcae)) {
            println("缓存更新: ${newChcae.data}")
            break
        }
    }
}


main () {
    let futureList = ArrayList<Future<Unit>>()

    for (i in 0..3) {
        let future = spawn {
            updateCache(i.toString())
        }

        // 将子线程对应的Future实例添加到list中
        futureList.add(future)
    }

    // 等待所有子线程执行结束
    for (future in futureList) {
        // 阻塞主线程
        future.get()
    }
}

四、小结

本章为大家详细的介绍了仓颉编程语言中原子操作的内容,下一章,为大家带来可重入互斥锁的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉服务端开发有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐