java lock同步访问

synchronized的缺点

如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程只能一直等待,有两种情况可以释放锁:

  1. 获取锁的线程执行完毕,然后线程释放锁。
  2. 线程执行发生异常,JVM会让线程自动释放锁。

如果调用sleep()方法或是其他原因被阻塞,但又没有释放锁,其他线程想要调用代码块就会一直等待。

Lock的特点和synchronized的区别

  1. Lock是一个接口,而synchronized是Java关键字,lock是内置的语言实现。
  2. synchronized在发生异常时,会自动释放线程占有的锁,因此不会造成死锁的发生,而Lock在发生异常时需要主动通过Unlock()方法解锁,否则很可能造成死锁。一般使用时在finally块中释放锁。
  3. Lock可以让等待锁的线程响应中断,而synchronized不行,如果没有获取到锁或者抛出异常,等待的线程会一直等待。
  4. Lock可以知道线程是否获取到锁,而synchronized无法办到。
  5. Lock可以提高多个线程进行读操作的效率。
  6. 性能上来说,如果资源竞争不是特别激烈,两者性能差不多。竞争非常激烈时lock的性能要远远优于synchronized,使用时要根据适当情况选择。
  7. synchronized和ReentrantLock都属于可重入锁。

常用的类和接口

一、Lock接口

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}
  • lock():获取锁,如果锁已经被其他线程获取,则进行等待。
  • tryLock():用来尝试获取锁,如果成功返回true,否则返回false。
  • tryLock(long time, TimeUnit unit):与同名方法类似,只不过在拿不到锁时会等待一段时间,等待时间内拿到锁或者在一开始就拿到锁会返回true,否则返回false。
  • lockInterruptibly():通过此方法去获取锁时,如果线程正在等待锁,则可以中断该线程的等待状态。(synchronized无法中断,只能一直进行)

二、ReentrantLock
属于可重入锁,唯一实现了Lock接口的类。

Lock lock=new ReentrantLock()//要注意不要新建到局部方法中,这样会造成加锁的不是一个对象,而是各个对象的复制
lock.lock();

三、ReadWriteLock
这是一个接口,其中只定义了两个方法:

  • readLock();
  • writeLock();

四、ReentrantReadWriteLock
ReadWriteLock的实现类,主要的就是接口中的两个方法用来获取读锁和写锁。
读锁可以使得多个线程同时读取,而不是synchronized关键字同一时间只能允许一个线程读取。

注意:

  • 如果有一个线程占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
  • 如果有一个线程占用了写锁,则此时其他线程如果要申请写锁或者读锁,则申请的线程会一直等待释放写锁。

概念:

可重入锁:比如在一个线程执行到synchronized方法method1时,如果method1中有另一个方法为method2也是synchronized修饰的,此时线程不必再申请锁,而是可以直接执行方法method2。即method1已经获取了锁,如果没有可重入性就会method2又申请锁,但此时method1已经有锁就会永远申请失败。
可中断锁: synchronized就是不可中断锁,lock可中断
公平锁: 尽量以请求锁的顺序来获取锁,比如有多个线程在等待一个锁,在锁释放时,等待时间最长的线程会获得该锁。synchronized无法保证顺序所以是非公平锁。ReentrantLock默认情况下是非公平锁,但可以设置为公平锁。
读写锁: 将一个文件的读写分离成两个锁,使得多线程的读操作可不冲突,ReadWriteLock就是读写锁。
参考资料:
https://www.cnblogs.com/dolphin0520/p/3923167.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值