我尝试编写一些关于 Lock 和 synchronized 的代码并比较它们的性能差异。
代码:
public abstract class Task {
public abstract int getTotal();
}
// Lock test class
public class TaskWithLock extends Task implements Runnable {
private static int total = 0;
private final Lock lock = new ReentrantLock();
public void run() {
try {
lock.lock();
doSomething();
} finally {
lock.unlock();
}
}
private void doSomething() {
total++;
}
public int getTotal() {
return total;
}
}
// Synchronized test class
public class TaskWithSync extends Task implements Runnable {
private static int total = 0;
public void run() {
synchronized ("") {
doSomething();
}
}
private void doSomething() {
total++;
}
public int getTotal() {
return total;
}
}
// Test class
public class Test {
public static void main(String[] args) throws Exception {
int count = 100000;
runTasks(TaskWithLock.class, count);
runTasks(TaskWithSync.class, count);
}
public static void runTasks(Class<? extends Runnable> clazz, int count)
throws Exception {
List<Thread> list = new ArrayList<Thread>(count);
for (int i = 0; i < count; i++) {
list.add(new Thread(clazz.newInstance()));
}
for (int i = 0; i < count; i++) {
list.get(i).start();
}
for (int i = 0; i < count; i++) {
list.get(i).join();
}
System.out.println(clazz.getSimpleName() + "Total Result: "
+ ((Task) clazz.newInstance()).getTotal());
}
}
我的理解是上面的Lock和synchronized代码块应该是一样的效果,但是我运行的结果不一样,synchronized代码是对的,总是100000,但是lock code总是不正确,有时候是99995,或者99997,或者其他结果,但不是 100000。
安慰:
TaskWithLock 结果:99991
TaskWithSync 结果:100000
我认为我的代码应该有一些错误,或者我对 Lock 的理解是错误的,或者 Lock 不能这样使用。
请指出可能有什么问题。