同步的java代码执行速度比不同步的代码快几倍
我在一个高并发应用程序上工作。在应用程序代码中,我尽量避免同步。最近,当比较非同步代码版本和同步代码版本的测试性能时,结果表明,同步代码的执行速度是非同步代码的三到四倍 经过一些实验,我得到了以下测试代码:同步的java代码执行速度比不同步的代码快几倍,java,concurrency,synchronization,Java,Concurrency,Synchronization,我在一个高并发应用程序上工作。在应用程序代码中,我尽量避免同步。最近,当比较非同步代码版本和同步代码版本的测试性能时,结果表明,同步代码的执行速度是非同步代码的三到四倍 经过一些实验,我得到了以下测试代码: private static final Random RND = new Random(); private static final int NUM_OF_THREADS = 3; private static final int NUM_OF_ITR = 3; private stat
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;
}
private static final Random RND=new Random();
私有静态final int NUM OF_线程=3;
私有静态最终int NUM OF_ITR=3;
私有静态最终int_工作负载=50000;
静态最终AtomicInteger锁=新的AtomicInteger();
专用静态void syncLockTest(布尔同步){
System.out.println(“syncLockTest,sync=“+sync”);
最终AtomicLong作业done=新的AtomicLong();
最终AtomicBoolean停止=新的AtomicBoolean();
for(int i=0;i10*1000){
打印时间=现在;
System.out.println(“作业完成\t”+jobsDone);
jobsDone.set(0);
i++;
}
试一试{
睡眠(1000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
停止。设置(true);
}
私有静态双[]monkeyJob(){
double[]res=新的double[MONKEY_工作负载];
for(int i=0;i
我考虑了线程数、工作负载、测试迭代次数——每次同步代码的执行速度都比未同步代码快得多
下面是两个不同的NUM_of_线程值的结果
线程数:3个syncLockTest,sync=true作业 完成5951个作业完成5958个作业完成5878个作业完成syncLockTest, sync=false
作业完成1399
作业完成1397
作业 完成1391
线程数:5个syncLockTest,sync=true
作业 完成5895个
作业完成6464个
作业完成5886个
同步锁测试, sync=false
完成的作业1179
完成的作业1260
完成1226
测试环境 Windows7专业版 Java 7.0版 这是一个类似的例子
有什么想法吗?Random是一个线程安全类。通过围绕主作业进行同步,很可能可以避免对随机类调用的争用。这很有趣。我想@jtahlborn已经搞定了。如果我将
随机
移动到线程的本地,则非同步跳转的时间约为10倍,而同步
跳转的时间不变:
以下是我使用静态随机RND
的时间:
syncLockTest, sync=true
Jobs done 8800
Jobs done 8839
Jobs done 8896
syncLockTest, sync=false
Jobs done 1401
Jobs done 1381
Jobs done 1423
以下是我使用每个线程的随机rnd
局部变量的时间:
syncLockTest, sync=true
Jobs done 8846
Jobs done 8861
Jobs done 8866
syncLockTest, sync=false
Jobs done 25956 << much faster
Jobs done 26065 << much faster
Jobs done 26021 << much faster
+你说得对!将rnd设置为局部变量后,将按预期执行非同步代码。谢谢!我认为格雷回答得很好。他能因此获得荣誉吗?
...
@Override
public void run() {
// made this be a thread local but it affected the times only slightly
double[] res = new double[MONKEY_WORKLOAD];
// turned rnd into a local variable instead of static
Random rnd = new Random();
while (!stop.get()) {
jobsDone.incrementAndGet();
if (sync) {
synchronized (lock) {
monkeyJob(res, rnd);
}
} else {
monkeyJob(res, rnd);
}
}
}
...
private static double[] monkeyJob(double[] res, Random rnd) {
for (int i = 0; i < res.length; i++) {
res[i] = rnd.nextDouble();
res[i] = 1. / (1. + res[i]);
}
return res;
}