即使我们在不同的线程中使用不同的锁,为什么值设置正确
Why is value set correctly even though we use different locks in different threads
即使我们在不同的线程中使用不同的锁,为什么 value
设置正确?
public class MyThread implements Runnable {
static String a = "LOCK";
static String b = "LOCK";
int id;
static int value = 0;
MyThread(int id) {
this.id = id;
}
@Override
public void run() {
if (id == 0) {
synchronized (a) {
for (int i = 0; i < Main.N; i++)
value = value + 3;
}
} else {
synchronized (b) {
for (int i = 0; i < Main.N; i++)
value = value + 3;
}
}
}
}
public class Main {
static final int N = 100000;
static int ITER = 100;
public static void main(String[] args) {
Thread threads[] = new Thread[2];
boolean sw = true;
for (int j = 0; j < ITER; j++) {
MyThread.value = 0;
for (int i = 0; i < 2; i++)
threads[i] = new Thread(new MyThread(i));
for (int i = 0; i < 2; i++)
threads[i].start();
for (int i = 0; i < 2; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (MyThread.value != 2 * 3 * N) {
System.out.println("i was different than " + 2 * 3 * N + ", it is " + MyThread.value);
sw = false;
}
}
if (sw)
System.out.println("Something is strange");
}
}
切勿将 String
用作锁,因为可能存在另一个 String
的相同实例,因为字符串池。
在你的例子中,你的两个 "LOCK"
字符串实际上是同一个对象。
Java 字符串文字被保留以节省内存。
你的两个 "LOCK"
字符串(因此你锁定的两个对象)实际上是同一个对象。
这就是(原因之一)为什么你永远不应该锁定原语。
即使我们在不同的线程中使用不同的锁,为什么 value
设置正确?
public class MyThread implements Runnable {
static String a = "LOCK";
static String b = "LOCK";
int id;
static int value = 0;
MyThread(int id) {
this.id = id;
}
@Override
public void run() {
if (id == 0) {
synchronized (a) {
for (int i = 0; i < Main.N; i++)
value = value + 3;
}
} else {
synchronized (b) {
for (int i = 0; i < Main.N; i++)
value = value + 3;
}
}
}
}
public class Main {
static final int N = 100000;
static int ITER = 100;
public static void main(String[] args) {
Thread threads[] = new Thread[2];
boolean sw = true;
for (int j = 0; j < ITER; j++) {
MyThread.value = 0;
for (int i = 0; i < 2; i++)
threads[i] = new Thread(new MyThread(i));
for (int i = 0; i < 2; i++)
threads[i].start();
for (int i = 0; i < 2; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (MyThread.value != 2 * 3 * N) {
System.out.println("i was different than " + 2 * 3 * N + ", it is " + MyThread.value);
sw = false;
}
}
if (sw)
System.out.println("Something is strange");
}
}
切勿将 String
用作锁,因为可能存在另一个 String
的相同实例,因为字符串池。
在你的例子中,你的两个 "LOCK"
字符串实际上是同一个对象。
Java 字符串文字被保留以节省内存。
你的两个 "LOCK"
字符串(因此你锁定的两个对象)实际上是同一个对象。
这就是(原因之一)为什么你永远不应该锁定原语。