Java里,synchronized和lock效率的简单比较

通常而言,我们可能都倾向于使用Lock来实现线程的同步,但是synchronized和lock究竟哪个效率高呢?

下面我们来做一个简单的对比实验,只比较最基础的部分,暂时不涉及等待和唤醒。

测试环境: JDK1.8

OS: win10 64bit

测试代码:

public class T {
	Lock lock = new ReentrantLock();
	
	public synchronized  void f() {
	}
	
	public void g() {
		lock.lock();
		lock.unlock();
	}

	public static void main(String[] args) throws InterruptedException {
		int count = 1000000000, i;
		long time = 0;
		T t = new T();
		
		time = System.currentTimeMillis();
		for (i = 0; i < count; i ++)
			t.f();
		System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		for (i = 0; i < count; i ++)
			t.g();
		System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		for (i = 0; i < count; i ++)
			t.f();
		System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		for (i = 0; i < count; i ++)
			t.g();
		System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		for (i = 0; i < count; i ++)
			t.f();
		System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		for (i = 0; i < count; i ++)
			t.g();
		System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
	}
}

测试结果:

Sync Time:4442
Lock Time:10824
Sync Time:2155
Lock Time:9592
Sync Time:2331
Lock Time:9550

结论:synchronized的效率远远高于lock操作,而且随着实验的重复,synchronized会进行优化,效率大概是Lock的2-4倍。

另类结论: 从循环的次数可以看出,无论是synchronized或者Lock,本身的效率已经非常高了,10亿次的操作,只需要10秒不到的时间,加锁一次大概需要10ns而已,synchronized大概只需要2ns。所以,其差距基本上也可以忽略不计了。

下面我们来进行更复杂一点的测试,以考验多线程环境下的效率。

测试代码:

public class T {
	Lock lock = new ReentrantLock();
	
	public synchronized  void f() {
		try {
		    Thread.sleep(1);
		} catch (Exception e) {
			
		}
		finally {
		}
	}
	
	public void g() {
		lock.lock();
		try {
		    Thread.sleep(1);
		} catch (Exception e) {
			
		}
		finally {
		    lock.unlock();
		}
	}

	public static void main(String[] args) throws InterruptedException {
		int count = 10000, i;
		long time = 0;
		ExecutorService workers = null;
		T t = new T();

		time = System.currentTimeMillis();
		workers = Executors.newFixedThreadPool(10);
		for (i = 0; i < count; i ++)
			workers.submit(() -> t.f());
		workers.shutdown();
		workers.awaitTermination(100000, TimeUnit.DAYS);
		System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		workers = Executors.newFixedThreadPool(10);
		for (i = 0; i < count; i ++)
			workers.submit(() -> t.g());
		workers.shutdown();
		workers.awaitTermination(100000, TimeUnit.DAYS);
		System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		workers = Executors.newFixedThreadPool(10);
		for (i = 0; i < count; i ++)
			workers.submit(() -> t.f());
		workers.shutdown();
		workers.awaitTermination(100000, TimeUnit.DAYS);
		System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
		
		time = System.currentTimeMillis();
		workers = Executors.newFixedThreadPool(10);
		for (i = 0; i < count; i ++)
			workers.submit(() -> t.g());
		workers.shutdown();
		workers.awaitTermination(100000, TimeUnit.DAYS);
		System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
		
	}
}

测试结果:

Sync Time:10028
Lock Time:7511
Sync Time:6938
Lock Time:4332
​

结论:synchronized在初始化时需要耗费较多事件,总的来说,多线程环境下Lock的效率更高一些。

这和网络上的结论基本是一致的,即如果竞争复杂,则使用Lock,如果竞争简单,则可使用synchronized

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值