I work on a high concurrency app. In the app code I try to avoid synchronization where possible. Recently, when comparing test performance of a unsynchronized and synchronized code versions, it turned out synchronized code performed three-four times faster than its unsynchronized counterpart.
After some experiments I came to this test code:
private static final Random RND = new Random();
private static final int NUM_OF_THREADS = 3;
private static final int NUM_OF_ITR = 3;
private static final int MONKEY_WORKLOAD = 50000;
static final AtomicInteger lock = new AtomicInteger();
private static void syncLockTest(boolean sync) {
System.out.println("syncLockTest, sync=" + sync);
final AtomicLong jobsDone = new AtomicLong();
final AtomicBoolean stop = new AtomicBoolean();
for (int i = 0; i < NUM_OF_THREADS; i++) {
Runnable runner;
if (sync) {
runner = new Runnable() {
@Override
public void run() {
while (!stop.get()){
jobsDone.incrementAndGet();
synchronized (lock) {
monkeyJob();
}
Thread.yield();
}
}
};
} else {
runner = new Runnable() {
@Override
public void run() {
while (!stop.get()){
jobsDone.incrementAndGet();
monkeyJob();
Thread.yield();
}
}
};
}
new Thread(runner).start();
}
long printTime = System.currentTimeMillis();
for (int i = 0; i < NUM_OF_ITR;) {
long now = System.currentTimeMillis();
if (now - printTime > 10 * 1000) {
printTime = now;
System.out.println("Jobs done\t" + jobsDone);
jobsDone.set(0);
i++;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stop.set(true);
}
private static double[] monkeyJob() {
double[] res = new double[MONKEY_WORKLOAD];
for (int i = 0; i < res.length; i++) {
res[i] = RND.nextDouble();
res[i] = 1./(1. + res[i]);
}
return res;
}
I played with the number of threads, workload, test iterations - each time synchronized code perfomed much faster than unsunchronized one.
Here are results for two different values of NUM_OF_THREADS
Number of threads:3
syncLockTest, sync=true
Jobs done 5951
Jobs done 5958
Jobs done 5878
syncLockTest, sync=false
Jobs done 1399
Jobs done 1397
Jobs done 1391Number of threads:5
syncLockTest, sync=true
Jobs done 5895
Jobs done 6464
Jobs done 5886
syncLockTest, sync=false
Jobs done 1179
Jobs done 1260
Jobs done 1226
Test environment Windows 7 Professional Java Version 7.0
Here's a simillar case Synchronized code performs faster than unsynchronized one
Any ideas?
Random is a thread-safe class. you are most likely avoiding contention on calls into the Random class by synchronizing around the main job.
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