synchronized 对性能的影响

 
	private static Object lock = new Object();

	public static void main(String[] args) {
		for (int k = 0; k < 10; k++) {
			long start = System.currentTimeMillis();
			for (int j = 0; j < 10000000; j++) {
				synchronized (lock) {
					int i = 1;
				}
			}
			System.out.println(System.currentTimeMillis() - start);

			start = System.currentTimeMillis();
			for (int j = 0; j < 10000000; j++) {
				int i = 1;
			}
			System.out.println(System.currentTimeMillis() - start);
		}

	}


输出

305
5
316
5
317
4
304
5
304
5
304
4
304
5
305
4
304
4
306
5


 

synchronized和ReentrantLock的性能不能一概而论,因为它们在不同的场景下表现可能会有所不同。早期版本的synchronized在很多场景下性能相差较大,但在后续版本中进行了较多改进,在低竞争场景中可能优于ReentrantLock。JDK6中synchronized加入了自适应自旋、锁消除、锁粗化、轻量级锁、偏向锁等一系列优化,官方也提倡在能满足需求的前提下优先考虑使用synchronized进行同步。[1][2] ReentrantLock是标准的乐观锁的实现,它通过内部的while循环判断锁是否被其他线程所持有,当其他线程持有锁时,就会一直自旋判断锁是否被释放。如果资源竞争激烈,同时锁竞争激烈,使用乐观锁可能会导致很多线程一直在循环等待,当线程数和执行时间达到一个临界值时,乐观锁的性能可能会比线程挂起的效率更低,循环等待的开销会大于线程挂起的开销。因此,当需要加锁的代码块执行时间普遍很长时,不建议使用ReentrantLock。[2] 另一方面,当资源竞争激烈,同时尝试获取锁的线程很多时,部分线程等待过久,如果使用synchronized,会导致锁慢慢膨胀,资源占有会越来越多。为了保证synchronized性能,加锁的代码块需要保证执行时间稳定,不会突然暴增。[2] 总的来说,synchronized和ReentrantLock在不同的场景下可能有不同的性能表现,需要根据具体情况选择合适的锁机制。synchronized在低竞争场景中可能优于ReentrantLock,而ReentrantLock则提供了更多的便利方法,可以进行精细的同步操作,甚至实现synchronized难以表达的用例。[1][3]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值