美文网首页
Java锁的使用,ReentrantLock,Reentrant

Java锁的使用,ReentrantLock,Reentrant

作者: 离别刀 | 来源:发表于2018-05-31 22:57 被阅读0次
80608152.png

在java中按照宏观认识上,一般分为乐观锁和悲观锁

乐观锁

通俗的讲就是某个操作读很多,写很少,遇到并发写入的情况非常少,大部分都是并发读,所以加锁就很不划算,但又不能杜绝这种情况,因此采用一种变通的方法来解决此问题,对某个数据的更新可以采用加版本号方法。比较本次的版本号和数据库的版本号是否一致,一致则更新,否则需要重新读取数据比较之后在写。

悲观锁

它与乐观锁刚好相反,读很少,容易出现并发写的情况,每次拿数据的时候都有可能已经不是最新的了,因此需要对该操作加锁,有且只有一个线程获得此锁,其它并发线程全部block住直到拿到锁。可以使用Synchronized对某个某方或者变量加锁,或者可以使用Lock对某片段代码加锁。
ReentrantLock类:

public interface Lock {
    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

    boolean tryLock(long var1, TimeUnit var3) throws InterruptedException;

    void unlock();

    Condition newCondition();
}

lock,unLock 对代码块加锁解锁,注意unlock必须写在finally里,可以当Synchronized使用。
tryLock方法可以判断是都能拿到锁
lockInterruptibly可以响应中断

ReentrantReadWriteLock 类:

public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading
     */
    Lock readLock();

    /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing
     */
    Lock writeLock();
}

readLock可以实现多个线程同时读
writeLock只能有一个线程写

Lock和synchronized的选择

Lock和synchronized有以下几点不同:
1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
5)Lock可以提高多个线程进行读操作的效率。
        在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。
转自网友:http://www.cnblogs.com/dolphin0520/p/3923167.html

相关文章

网友评论

      本文标题:Java锁的使用,ReentrantLock,Reentrant

      本文链接:https://www.haomeiwen.com/subject/fidqsftx.html