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());
}
}
私の理解では、上記のロックと同期コード ブロックは同じ効果であるはずですが、それらを実行した結果は同じではなく、同期コードは正しく、常に 100000 ですが、ロック コードは常に正しくなく、時には 99995、99997、または他の結果ですが、100000 ではありません。
コンソール:
TaskWithLock 結果: 99991
TaskWithSync 結果: 100000
私のコードに何らかのエラーがあるはずだと思います。または、ロックに関する私の理解が間違っているか、ロックがこのように使用できません。
間違っている可能性があることを指摘してください。