Synchronized和Lock区别

2020-03-15  本文已影响0人  anjian8000

由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。在分布式开发中,锁是线程控制的重要途径。Java为此也提供了2种锁机制,synchronized和lock。

1.synchronized

示例1:

private void synMethod() {

    doSomething();

    //代码块加锁

    synchronized (this) {

        doSomething1();

    }

    doSomething2();

}

示例2:

//方法上加锁,可以锁住整个方法,保证数据安全性,但是相对代码块加锁,性能上有稍微影响

private synchronized void synMethod() {

    doSomething1();

    doSomething1();

    doSomething2();

}

所以建议高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁。这里对象锁和类锁不做介绍,感兴趣的同学可以去查下资料(相信大家从名字上就可以猜测到它们的区别)

2.lock

一般使用ReentrantLock类做为锁,多个线程中必须要使用一个ReentrantLock类做为对象才能保证锁的生效。且在加锁和解锁处需要通过lock()和unlock()显示指出。所以一般会在finally块中写unlock()以防死锁。

示例:

ReentrantLocklock = new ReentrantLock();

// ...

lock.lock();

try {

    doSomething();

    doOthers();

} finally {

    lock.unlock();

}

总结:synchronized是托管给JVM执行的,而lock是java写的控制锁的代码。在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地。所以在jdk新的版本中我们一般会使用synchronize更多一些。

上一篇下一篇

猜你喜欢

热点阅读