关于JAVA多线程并发synchronized的测试与合理使用(二)

2014-11-24 11:17:31 · 作者: · 浏览: 3
8ms
doAdd2() => i=9, spendTime=188ms
doAdd2() => i=9, spendTime=188ms
doAdd2() => i=9, spendTime=188ms
doAdd2() => i=9, spendTime=188ms
doAdd2() => i=9, spendTime=188ms
doAdd2() => i=9, spendTime=188ms
doAdd2() => i=9, spendTime=188ms
doAdd2() => i=9, spendTime=188ms
doAdd1() => i=10, spendTime=391ms
doAdd1() => i=11, spendTime=610ms
doAdd1() => i=12, spendTime=813ms
doAdd1() => i=13, spendTime=1016ms
doAdd1() => i=14, spendTime=1219ms
doAdd1() => i=15, spendTime=1422ms
doAdd1() => i=16, spendTime=1610ms
doAdd1() => i=17, spendTime=1813ms
doAdd1() => i=18, spendTime=2016ms
花费时间:12994ms
doAdd2方法瞬间执行完成, 之后doAdd1方法则是串行有序执行. 这时doAdd2方法获取的变量值已经错乱, doAdd1获取的正常. 花费时间:12994ms
3. 两个方法在都没使用synchronized前的情况:
执行结果:
[java]
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd1() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
doAdd2() => i=16, spendTime=203ms
花费时间:4060ms
可以看到, 两个方法的变量值获取已经错乱, 但花费时间最少4060ms
4. 使用同步块, 在两个方法内采用不同的对象锁:
doAdd1:
[java]
synchronized (obj1)
{
Thread.sleep(100);
++i;
Thread.sleep(100);
return i;
}
doAdd2:
[java]
synchronized (obj2)
{
Thread.sleep(100);
++i;
Thread.sleep(100);
return i;
}
执行结果:
[html]
doAdd1() => i=2, spendTime=203ms
doAdd2() => i=2, spendTime=203ms
doAdd1() => i=4, spendTime=406ms
doAdd2() => i=4, spendTime=406ms
doAdd1() => i=6, spendTime=609ms
doAdd2() => i=6, spendTime=609ms
doAdd1() => i=8, spendTime=812ms
doAdd2() => i=8, spendTime=812ms
doAdd1() => i=10, spendTime=1000ms
doAdd2() => i=10, spendTime=1015ms
doAdd1() => i=12, spendTime=1203ms
doAdd2() => i=12, spendTime=1203ms
doAdd1() => i=14, spendTime=1406ms
doAdd2() => i=14, spendTime=1406ms
doAdd1() => i=16, spendTime=1609ms
doAdd2() => i=16, spendTime=1609ms
doAdd1() => i=18, spendTime=1812ms
doAdd2() => i=18, spendTime=1812ms
doAdd1() => i=20, spendTime=2015ms
doAdd2() => i=20, spendTime=2015ms
花费时间:22165ms
两个方法有序交替执行, 互不影响, 花费时间:22165ms, 相对加锁同一对象执行的时间缩短.
5. 使用同步块, 使用方法参数作为对象锁:
[java]
public Integer doAdd1(Long start) throws Exception
{
synchronized (start)
{
Thread.sleep(100);
++i;
Thread.sleep(100);
return i;
}
}
执行结果:
[java]
doAdd1() => i=15, spendTime=203ms
doAdd1() => i=15, spendTime=203ms
doAdd1() => i=15, spendTime=203ms
doAdd1() => i=15, spendTime=203ms
doAdd1() => i=15, spendTime=203ms