为什么这个java程序的输出除了一个?;
我正在编写一些代码来模拟CAS(比较和交换)。为什么这个java程序的输出除了一个?;,java,concurrency,Java,Concurrency,我正在编写一些代码来模拟CAS(比较和交换)。 这里我有一个方法cas来模拟cas指令,一个方法将增加到+fieldcount1。我启动两个线程,每个线程添加字段count10000次。 问题是,预期产量是20000,但实际产量比20000稍小。例如199841999219989…每一次都是不同的。 如果你能帮助我,我将非常感激 public class SimulateCAS { private volatile int count; private synchronized
这里我有一个方法
cas
来模拟cas指令,一个方法将增加到+fieldcount
1。我启动两个线程,每个线程添加字段count
10000次。
问题是,预期产量是20000,但实际产量比20000稍小。例如199841999219989…每一次都是不同的。
如果你能帮助我,我将非常感激
public class SimulateCAS {
private volatile int count;
private synchronized int cas(int expectation, int newValue) {
int curValue = count;
if (expectation == curValue) {
count = newValue;
}
return curValue;
}
void increase() {
int newValue;
do {
newValue = count + 1; // ①
} while (count != cas(count, newValue)); // ②
}
public static void main(String[] args) throws InterruptedException {
final SimulateCAS demo = new SimulateCAS();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
demo.add10k();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
demo.add10k();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(demo.count);
}
}
公共类模拟器{
私有可变整数计数;
专用同步int-CA(int-expectation,int-newValue){
int曲线值=计数;
if(期望值==曲线值){
计数=新值;
}
返回曲线值;
}
空隙增加(){
int新值;
做{
newValue=count+1;//①
}while(count!=cas(count,newValue));//②
}
公共静态void main(字符串[]args)引发InterruptedException{
最终SimulateCAS演示=新SimulateCAS();
线程t1=新线程(()->{
对于(int i=0;i<10000;i++){
demo.add10k();
}
});
线程t2=新线程(()->{
对于(int i=0;i<10000;i++){
demo.add10k();
}
});
t1.start();
t2.start();
t1.join();
t2.连接();
System.out.println(demo.count);
}
}
问题在于您的增加方法
count
的值可以在带有注释的行之间的任意点更新① 及②.
您的增加
的实现假定这不会发生,并且计数
在一行中① 与第行中的计数相同②.
一个更好的实现方法是
void increase() {
int oldValue, newValue;
do {
oldValue = count; // get the current value
newValue = oldValue + 1; // calculate the new value based on the old
} while (oldValue != cas(oldValue, newValue)); // Do a compare and swap - if the oldValue is still the current value, change it to the newValue, otherwise not.
}
您的完整代码具有真正的CAS,因此不需要锁。这不是问题,但是add10k
不应被称为“add10k”,因为该函数没有添加10k。它应该被称为increment
或类似的东西。你是对的。谢谢你的建议。我想问题出在两行之间① 和线②, 但我无法解释和解决它。谢谢你的回答!每次使用count
都是自己读取的。因此,如果该值在1和2之间更改,则可能会错过更新。