H-B*_*Bar 0 java concurrency synchronized
我最近遇到了这个代码片段
class Counter2 implements Runnable{
private int value = 0;
private Integer lock = 0;
public void increment(){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
value++;
}
public void decrement(){
value--;
}
public int getValue() {
return value;
}
@Override
public void run() {
synchronized(lock) {
this.increment();
System.out.println(String.format("%s incremented value, value = %s", Thread.currentThread().getName(), this.value));
this.decrement();
System.out.println(String.format("%s decremented value, value = %s", Thread.currentThread().getName(), this.value));
}
}
}
public class Part8_synchronized_keyword_1 {
public static void main(String[] args) {
Counter2 counter = new Counter2();
new Thread(counter,"Thread1").start();
new Thread(counter,"Thread2").start();
new Thread(counter,"Thread3").start();
new Thread(counter,"Thread4").start();
Counter2 counterB = new Counter2();
new Thread(counterB, "ThreadB").start();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出如下
Thread1 incremented value, value = 1
Thread1 decremented value, value = 0
ThreadB incremented value, value = 1
ThreadB decremented value, value = 0
Thread4 incremented value, value = 1
Thread4 decremented value, value = 0
Thread3 incremented value, value = 1
Thread3 decremented value, value = 0
Thread2 incremented value, value = 1
Thread2 decremented value, value = 0
Run Code Online (Sandbox Code Playgroud)
为什么看起来 threadB 正在与 thread1...4 竞争同一个锁?因为根据我的理解,counterB 和 counter 的锁对象会有所不同
您认为counter
和counterB
使用不同锁的假设是错误的。
为什么:因为你将你的锁声明为
\nprivate Integer lock = 0;\n
Run Code Online (Sandbox Code Playgroud)\nJVM 缓存Integer
从 -128 到 127 之间所有值的对象。
将你的锁声明为
\nprivate Object lock = new Object();\n
Run Code Online (Sandbox Code Playgroud)\n然后才会counter
使用counterB
不同的锁!
请注意对象引用和被引用对象之间的重要区别:
\n和counter
都有counterB
一个字段lock
,但这些字段不是对象,它们只是对某个对象的引用。
为了
\nprivate Integer lock = 0;\n
Run Code Online (Sandbox Code Playgroud)\n引用“某个对象”对于counter
and来说是相同的counterB
(因为 Java 语言规范要求将int
-128 到 127 范围内的值装箱),并且同步发生在对象上,而不是引用上。
\n\n如果装箱的值是计算、、、、或
\np
类型的常量表达式 (\xc2\xa715.29) 的结果,并且结果是、 、包含范围内的字符或范围内的整数为包容性,然后令和为 的任意两个装箱转换的结果。情况总是如此。boolean
byte
char
short
int
long
true
false
\'\\u0000\'
\'\\u007f\'
-128
127
a
b
p
a == b
归档时间: |
|
查看次数: |
69 次 |
最近记录: |