嘿,我正在 kotlin 中學習原子。我想知道在我的場景中使用原子布林值是個好主意嗎?有人可以建議,如何以原子方式進行。
場景 1不是第一次呼叫
var isFirstTime = true
fun notForFirstTime(){
if(!isFirstTime){
jobDone()
}
isFirstTime = false
}
場景 2僅適用于第一次
var isFirstTime = true
fun onlyForFirstTime(){
if(isFirstTime){
jobDone()
}
isFirstTime = false
}
我可以以原子方式做到這一點嗎?這也是個好主意嗎?
uj5u.com熱心網友回復:
這取決于您要達到的目標。
對于場景 2,大多數時候您想要的是一個計算一次并在以后重用的值。對于這個用例,您可以lazy像這樣使用委托:
class MyClass {
// will be computed the first time it's accessed, and then reused
val value by lazy { computeExpensiveValue() }
}
fun computeExpensiveValue(): Int {
// some complex stuff
return 42
}
我從來沒有遇到過場景 1,但如果lazy還不夠的話,您確實可以將原子布林值用于 CAS 方法或鎖。檢查例如kotlinx.atomicfu。
如果您使用的是 Kotlin 協程,您可能需要檢查其他同步原語,例如Mutex和Semaphore。但總的來說,最好讓協程通過通道進行通信,而不是共享可變狀態。
uj5u.com熱心網友回復:
你問什么不是很清楚。但是假設您想確保某些代碼僅在第一次執行(或不執行)并且該函式可以同時呼叫(因為您要求“原子”),那么答案是:不和不。您的兩個代碼示例都不是執行緒安全的,并且可能導致以特殊方式處理的第一次呼叫不止一次。
這不是因為 boolean 不是原子的,而是因為您的代碼不是原子的。兩個或多個并發執行緒可以同時檢查isFirstTime,然后其他執行緒將其翻轉為false.
您可以通過多種方式解決此問題,例如使用互斥鎖,但可能最簡單和最高效的方法是使用比較和交換操作之一。例如:
val isFirstTime = AtomicBoolean(true)
fun notForFirstTime(){
if (!isFirstTime.getAndSet(false)) {
jobDone()
}
}
fun onlyForFirstTime(){
if (isFirstTime.getAndSet(false)) {
jobDone()
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/430320.html
