I try to write some code about Lock and synchronized and to compare their performance difference.
Code:
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());
}
}
My understand is the above Lock and synchronized code block should be the same effect, but the result I run them are not same, synchronized code is right, it is always 100000, but lock code is always incorrect, sometimes 99995,or 99997, or other result, but it is not 100000.
Console:
TaskWithLock Result: 99991
TaskWithSync Result: 100000
I think my code should have some error, or my understand about Lock is wrong, or Lock can not be used like this.
Please point out what could be wrong.
In the lock-version, you are using one lock per instance. That means that every thread has its own lock, which ultimately renders the locks useless because no two threads use the same lock.
You need to change this to one central lock for all threads. Add static to this line:
private final Lock lock = new ReentrantLock();
so it becomes
private static final Lock lock = new ReentrantLock();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With