java锁的问题
程序员文章站
2022-07-12 19:38:58
...
参考网上的例子,写了一个并发场景下的乐观锁demo,引出了一个新问题:锁的本质是什么?将内存中的一块区域只让一个线程访问?下面的get方法是只读的,它的上锁与否为什么对加法成功的效率有质的影响呢?
public class SimulatedCAS {
private int value;
public SimulatedCAS(int value) {
this.value = value;
}
/** 此处上锁成功率要高很多,原因不清楚,讲道理,锁应该是锁的方法,不是value呀 */
public synchronized int get(){
return value;
}
public synchronized boolean casAdd(int expectedValue, int newValue){
// try {
// Thread.sleep(300);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
if(this.value == expectedValue){//如果期望值与当前V位置的值相同就给予新值
value = newValue;
return true;
}
return false;//返回V位置原有的值
}
public static void main(String[] args) throws Exception {
SimulatedCAS casObj = new SimulatedCAS(10);
Runnable r = new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
long currentTimeMillis = System.currentTimeMillis();
Random rand = new Random();
int nextInt = rand.nextInt(10) + 1;
boolean succ = false;
do {
int oldValue = casObj.get();
int newValue = oldValue+nextInt;
succ = casObj.casAdd(oldValue, newValue);
int resultValue = casObj.get();
System.out.println(currentTimeMillis + "#" + threadName + "#" + oldValue + "~" + newValue
+ "\n\t随机数:" + nextInt + "\t操作结果:" + succ
+ "\t 操作:" + oldValue + " + " + nextInt + " = " + resultValue);
} while(!succ);
}
};
List<Thread> tList = new ArrayList<>();
for (int i = 0; i < 6; i++) {
Thread t = new Thread(r);
t.setName("thread" + i);
tList.add(t);
t.start();
}
for (Thread thread : tList) {
thread.join();
}
System.out.println("result: " + casObj.get());
}
}
=======================================================
1626430679911#thread3#10~18
随机数:8 操作结果:true 操作:10 + 8 = 18
1626430679911#thread4#10~11
随机数:1 操作结果:false 操作:10 + 1 = 22
1626430679911#thread0#10~11
随机数:1 操作结果:false 操作:10 + 1 = 18
1626430679911#thread5#18~28
随机数:10 操作结果:false 操作:18 + 10 = 22
1626430679911#thread1#10~19
随机数:9 操作结果:false 操作:10 + 9 = 18
1626430679911#thread1#34~43
随机数:9 操作结果:true 操作:34 + 9 = 43
1626430679912#thread2#18~22
随机数:4 操作结果:true 操作:18 + 4 = 22
1626430679911#thread5#24~34
随机数:10 操作结果:true 操作:24 + 10 = 34
1626430679911#thread0#23~24
随机数:1 操作结果:true 操作:23 + 1 = 24
1626430679911#thread4#22~23
随机数:1 操作结果:true 操作:22 + 1 = 23
result: 43
public class SimulatedCAS {
private int value;
public SimulatedCAS(int value) {
this.value = value;
}
/** 此处上锁成功率要高很多,原因不清楚,讲道理,锁应该是锁的方法,不是value呀 */
public synchronized int get(){
return value;
}
public synchronized boolean casAdd(int expectedValue, int newValue){
// try {
// Thread.sleep(300);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
if(this.value == expectedValue){//如果期望值与当前V位置的值相同就给予新值
value = newValue;
return true;
}
return false;//返回V位置原有的值
}
public static void main(String[] args) throws Exception {
SimulatedCAS casObj = new SimulatedCAS(10);
Runnable r = new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
long currentTimeMillis = System.currentTimeMillis();
Random rand = new Random();
int nextInt = rand.nextInt(10) + 1;
boolean succ = false;
do {
int oldValue = casObj.get();
int newValue = oldValue+nextInt;
succ = casObj.casAdd(oldValue, newValue);
int resultValue = casObj.get();
System.out.println(currentTimeMillis + "#" + threadName + "#" + oldValue + "~" + newValue
+ "\n\t随机数:" + nextInt + "\t操作结果:" + succ
+ "\t 操作:" + oldValue + " + " + nextInt + " = " + resultValue);
} while(!succ);
}
};
List<Thread> tList = new ArrayList<>();
for (int i = 0; i < 6; i++) {
Thread t = new Thread(r);
t.setName("thread" + i);
tList.add(t);
t.start();
}
for (Thread thread : tList) {
thread.join();
}
System.out.println("result: " + casObj.get());
}
}
=======================================================
1626430679911#thread3#10~18
随机数:8 操作结果:true 操作:10 + 8 = 18
1626430679911#thread4#10~11
随机数:1 操作结果:false 操作:10 + 1 = 22
1626430679911#thread0#10~11
随机数:1 操作结果:false 操作:10 + 1 = 18
1626430679911#thread5#18~28
随机数:10 操作结果:false 操作:18 + 10 = 22
1626430679911#thread1#10~19
随机数:9 操作结果:false 操作:10 + 9 = 18
1626430679911#thread1#34~43
随机数:9 操作结果:true 操作:34 + 9 = 43
1626430679912#thread2#18~22
随机数:4 操作结果:true 操作:18 + 4 = 22
1626430679911#thread5#24~34
随机数:10 操作结果:true 操作:24 + 10 = 34
1626430679911#thread0#23~24
随机数:1 操作结果:true 操作:23 + 1 = 24
1626430679911#thread4#22~23
随机数:1 操作结果:true 操作:22 + 1 = 23
result: 43