java的两种锁解析

两种锁的概述
1.syncchronized锁。这种锁的同步监视器是对象或者类。分为同步代码块和同步方法。
synchronized:
包括synchronized方法和synchronized块。
synchronized方法使用this作为默认的“同步监视器”,而synchronized块则需自行指定。
wait、notify、notifyAll必须在同步方法或块中,否则会抛出异常
Object.wait:
要执行obj.wait,当前线程必须拥有obj的监视器(monitor)
执行后会导致当前线程进入等待,直到其它线程调用obj.notify或obj.notifyAll
执行后当前线程会放弃在obj上的所有同步请求(synchronization claims)
注意只是使当前线程处于等待,但对同步方法/块的占有却释放了,所以其它线程便可以随后访问这个同步方法/块了
Object.notify,Object.notifyAll:
要执行obj.notify、obj.notifyAll,当前线程必须拥有obj的监视器(monitor)
obj.notify会随机唤醒一个等待在obj上的线程,而obj.notifyAll却会唤醒所有等待在obj上的线程
被唤醒的线程不能马上执行,直到当前线程放弃obj的同步锁(The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. ),也就是当前线程离开了同步方法/块后

2.Lock
常用的是ReentranLock(可重入锁),可以显示地加锁,释放锁。

3.两种锁的区别:
(1)synchronized自动释放锁,Lock显示释放。
(2)Lock更加灵活。
(3)synchronized锁的是对象或者类,Lock锁的是Lock对象。

4.锁的作用范围:
锁的作用范围是当前线程

—————-分割线———————–

关于可重入锁
概念:可重入锁是指当一个线程可以递归或者重复地获得同一个锁。
具体例子可以参考:
https://segmentfault.com/a/1190000000393427#articleHeader2

—————-分割线———————–

关于如何正确地释放锁
1.synchronized会自动释放锁。
2.Lock要在finally中释放锁。
如果用Lock来保护临界区,并且临界区有可能会抛出异常,那么在finally语句中调用unlock()就显得非常重要了。这样可以保证这个锁对象可以被解锁以便其它线程能继续对其加锁。以下是一个示例:

lock.lock();
try{
    //do critical section code, //which may throw exception } finally { lock.unlock();
}

这个简单的结构可以保证当临界区抛出异常时Lock对象可以被解锁。如果不是在finally语句中调用的unlock(),当临界区抛出异常时,Lock对象将永远停留在被锁住的状态,这会导致其它所有在该Lock对象上调用lock()的线程一直阻塞。

—————-分割线———————–

关于锁的公平性
如果查看 Javadoc,您会看到, ReentrantLock 构造器的一个参数是 boolean 值,它允许您选择想要一个 公平(fair)锁,还是一个 不公平(unfair)锁。公平锁使线程按照请求锁的顺序依次获得锁;而不公平锁则允许讨价还价,在这种情况下,线程有时可以比先请求锁的其他线程先得到锁。
为什么我们不让所有的锁都公平呢?毕竟,公平是好事,不公平是不好的,不是吗?(当孩子们想要一个决定时,总会叫嚷“这不公平”。我们认为公平非常重要,孩子们也知道。)在现实中,公平保证了锁是非常健壮的锁,有很大的性能成本。要确保公平所需要的记帐(bookkeeping)和同步,就意味着被争夺的公平锁要比不公平锁的吞吐率更低。作为默认设置,应当把公平设置为 false ,除非公平对您的算法至关重要,需要严格按照线程排队的顺序对其进行服务。
那么同步又如何呢?内置的监控器锁是公平的吗?答案令许多人感到大吃一惊,它们是不公平的,而且永远都是不公平的。但是没有人抱怨过线程饥渴,因为 JVM 保证了所有线程最终都会得到它们所等候的锁。确保统计上的公平性,对多数情况来说,这就已经足够了,而这花费的成本则要比绝对的公平保证的低得多。所以,默认情况下 ReentrantLock 是“不公平”的,这一事实只是把同步中一直是事件的东西表面化而已。如果您在同步的时候并不介意这一点,那么在 ReentrantLock 时也不必为它担心。

    原文作者:java锁
    原文地址: https://blog.csdn.net/guangmomo/article/details/51241948
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞