我为一个问题所困扰,
如果只有一个线程写入变量,而另一个线程只是读取变量,我们应该添加锁吗?
所以我写了这样的代码进行测试
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
var lock sync.RWMutex
var i = 0
func main() {
runtime.GOMAXPROCS(2)
go func() {
for {
fmt.Println("i am here", i)
time.Sleep(time.Second)
}
}()
for {
i += 1
}
}
即使经过一秒钟,结果仍保持打印i am here 0
。我对内存屏障或cpu缓存有所了解。但是怎么会这么长时间缓存呢?我认为一段时间后,它应该读取我已经更改的变量。
请高手或计算机系统的任何人可以帮助回答?
更新:我知道这样更新变量是错误的方法,我想知道为什么在cpu /内存视图中未定义它。
答案 0 :(得分:4)
您有一场数据竞赛。因此,结果是不确定的。
search.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int start, int before, int count) {
// TODO Auto-generated method stub
int textlength = cs.length();
String text = cs.toLowerCase(Locale.getDefault());
adapter.filter(text);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
输出:
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
var lock sync.RWMutex
var i = 0
func main() {
runtime.GOMAXPROCS(2)
go func() {
for {
fmt.Println("i am here", i)
time.Sleep(time.Second)
}
}()
for {
i += 1
}
}
参考文献:
答案 1 :(得分:1)
如果只有一个线程写入变量,而另一个线程只是读取变量,我们应该添加锁吗?
是的。总是。这里没有争论。
您的测试代码无法证明或拒绝任何行为,因为其行为未定义。
答案 2 :(得分:0)
最后,我找到了这个答案,我知道通过数据竞赛,您将获得不确定的行为,但是我想知道为什么它目前的行为如此。
此快照代码是因为编译器仅删除添加功能,而从不添加。
所以我们有一个教训,如果你写一个不确定的行为,你可能会得到一个月亮--
编译器会将您的代码视为垃圾,它没有任何价值。