Java中的锁synchronized和lock的用法和比较

一、synchronized和lock的简单使用

synchronized可以用在方法和代码块上,保证被包裹代码在多线程环境下的数据安全性,synchronized是java语言内置的,lock是jdk提供的一个接口,实现类主要有ReentrantLock、ReadLock、WriteLock,lock在使用的时候通过lock()方法获取锁,通过unlock()方法释放锁,这是都是程序员手动完成。synchronized和lock都是支持可重入的。

synchronized在用法上简单,在没有特殊情况下,尽量使用此方法,而在获取锁可以被中断,超时获取锁,尝试获取锁,读多写少用读写锁等情况下,使用lock接口更好。

二、synchronized和lock的公平锁、非公平锁以及读写锁

所谓公平锁和非公平锁是指在多线程下,是否可以保证先等待的线程拥有优先执行权,如果可以保证,就是公平锁,不能保证的就是非公平锁,从效率上来讲,非公平锁的效率更高,因为实现公平锁,要挂起等待的线程,频繁挂起和释放影响了效率。synchronized就是一个非公平锁,被等待的线程有同样的机会获取CPU的执行权,而ReentrantLock同过初始化可以指定使用公平锁和非公平锁,如果不指定,默认非公平锁。

public ReentrantLock() {
    sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

synchronized包裹的代码在多线程下只能有一个线程去执行,所以我们应该尽量减少包裹的代码量,只包裹数据发生变化的代码即进行写操作的代码,否则十分影响效率,而ReadWriteLock接口的实现类ReentrantReadWriteLock读写锁可以实现多个线程进行读操作,当执行写操作时,线程阻塞,ReentrantReadWriteLock内部的读、写锁都实现自lock接口。

三、synchronized和lock的等待唤醒机制

synchronized中使用wait()和notify()、notifyAll()方法实现等待唤醒机制,wait()和notify()、notifyAll()都是属于object对象的方法,在使用lock时,则借助于Condition类的await()和signal()、signalAll()方法来实现,通过lock.newCondition()方法返回一个Condition对象,使用对象的await、signal方法实现等待唤醒。需要注意的是一个lock可以获得多个Condition对象,对不同情况获取不能的Condition对象,在synchronized中我们只能有一个锁,即等待和唤醒用的是一样的锁,所以在synchronized中要求使用notifyAll(),而不是notify(),否则很容易造成线程阻塞,而使用Condition时推荐使用signal()方法。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值