原子操作是指在多线程中的一个不可分割的操作单元。在一个原子操作中,要么所有步骤都执行,要么所有操作都不执行。比如:在进行转账的时候,甲向乙转账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.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() } }四、小结
本章为大家详细的介绍了仓颉编程语言中原子操作的内容,下一章,为大家带来可重入互斥锁的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉服务端开发有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!