java 同步 变量_java – 对局部变量的同步

这是一个手动“

lock coarsening”的例子,可能已经做了,以提高性能。

考虑这两个片段:

StringBuffer b = new StringBuffer();

for(int i = 0 ; i < 100; i++){

b.append(i);

}

与:

StringBuffer b = new StringBuffer();

synchronized(b){

for(int i = 0 ; i < 100; i++){

b.append(i);

}

}

在第一种情况下,StringBuffer必须获取和释放锁定100次(因为append是一种同步方法),而在第二种情况下,锁定被获取并释放一次。这可以给你一个性能提升,可能是为什么作者做到了。在某些情况下,编译器可以为你执行这个lock coarsening(但不是在循环结构,因为你可能最终持有一个锁很长一段时间)。

顺便说一下,编译器可以检测到一个对象不是从一个方法“转义”,所以删除获取和释放对象的锁(锁定elision),因为没有其他线程可以访问该对象。在JDK7年已经做了很多工作。

更新:

我进行了两个快速测试:

1)无需预热:

在这个测试中,我没有运行这些方法几次来“热身”JVM。这意味着Java热点服务器编译器没有得到优化代码的机会。通过消除逃逸对象的锁。

JDK 1.4.2_19 1.5.0_21 1.6.0_21 1.7.0_06

WITH-SYNC (ms) 3172 1108 3822 2786

WITHOUT-SYNC (ms) 3660 801 509 763

STRINGBUILDER (ms) N/A 450 434 475

使用JDK 1.4,具有外部同步块的代码更快。然而,使用JDK 5及以上的代码没有外部同步赢。

2)带温度:

在该测试中,在计算时间之前,将方法运行几次。这样做使JVM可以通过执行转义分析来优化代码。

JDK 1.4.2_19 1.5.0_21 1.6.0_21 1.7.0_06

WITH-SYNC (ms) 3190 614 565 587

WITHOUT-SYNC (ms) 3593 779 563 610

STRINGBUILDER (ms) N/A 450 434 475

再次,使用JDK 1.4,具有外部同步块的代码更快。但是,使用JDK 5及更高版本,两种方法的性能同样良好。

这里是我的测试类(随意改善):

public class StringBufferTest {

public static void unsync() {

StringBuffer buffer = new StringBuffer();

for (int i = 0; i < 9999999; i++) {

buffer.append(i);

buffer.delete(0, buffer.length() - 1);

}

}

public static void sync() {

StringBuffer buffer = new StringBuffer();

synchronized (buffer) {

for (int i = 0; i < 9999999; i++) {

buffer.append(i);

buffer.delete(0, buffer.length() - 1);

}

}

}

public static void sb() {

StringBuilder buffer = new StringBuilder();

synchronized (buffer) {

for (int i = 0; i < 9999999; i++) {

buffer.append(i);

buffer.delete(0, buffer.length() - 1);

}

}

}

public static void main(String[] args) {

System.out.println(System.getProperty("java.version"));

// warm up

for(int i = 0 ; i < 10 ; i++){

unsync();

sync();

sb();

}

long start = System.currentTimeMillis();

unsync();

long end = System.currentTimeMillis();

long duration = end - start;

System.out.println("Unsync: " + duration);

start = System.currentTimeMillis();

sync();

end = System.currentTimeMillis();

duration = end - start;

System.out.println("sync: " + duration);

start = System.currentTimeMillis();

sb();

end = System.currentTimeMillis();

duration = end - start;

System.out.println("sb: " + duration);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值