java自旋锁代码大全 java自旋锁使用( 二 )


对于Synchronized而言 , 当然是独享锁 。
分段锁
分段锁其实是一种锁的设计,并不是具体的一种锁 。对于ConcurrentHashMap而言 , 其并发的实现就是通过分段锁的形式来实现高效的并发操作 。
我们以ConcurrentHashMap来说一下分段锁的含义以及设计思想,ConcurrentHashMap中的分段锁称为Segment,它即类似于HashMap(JDK7与JDK8中HashMap的实现)的结构,即内部拥有一个Entry数组,数组中的每个元素又是一个链表;同时又是一个ReentrantLock(Segment继承了ReentrantLock) 。
当需要put元素的时候,并不是对整个hashmap进行加锁,而是先通过hashcode来知道他要放在那一个分段中,然后对这个分段进行加锁,所以当多线程put的时候,只要不是放在一个分段中,就实现了真正的并行的插入 。
但是,在统计size的时候 , 可就是获取hashmap全局信息的时候 , 就需要获取所有的分段锁才能统计 。
分段锁的设计目的是细化锁的粒度,当操作不需要更新整个数组的时候,就仅仅针对数组中的一项进行加锁操作 。
互斥锁:
无法获取琐时,进线程立刻放弃剩余的时间片并进入阻塞(或者说挂起)状态 , 同时保存寄存器和程序计数器的内容(保存现?。舷挛那谢坏那鞍氩糠郑? ,当可以获取锁时,进线程激活 , 等待被调度进CPU并恢复现?。ㄉ舷挛那谢幌掳氩糠郑?
上下文切换会带来数十微秒的开销,不要在性能敏感的地方用互斥锁
读写锁:
1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
3)写者优先于读者(一旦有写者 , 则后续读者必须等待 , 唤醒时优先考虑写者)
自旋锁:
自旋锁是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU 。
Java锁有哪些种类,以及区别一、公平锁/非公平锁
公平锁是指多个线程按照申请锁java自旋锁代码大全的顺序来获取锁 。
非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序 , 有可能后申请的线程比先申请的线程优先获取锁 。有可能,会造成优先级反转或者饥饿现象 。
对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁 。非公平锁的优点在于吞吐量比公平锁大 。
对于Synchronized而言,也是一种非公平锁 。由于其并不像ReentrantLock是通过AQS的来实现线程调度 , 所以并没有任何办法使其变成公平锁 。
二、可重入锁
可重入锁又名递归锁 , 是指在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁 。说的有点抽象 , 下面会有一个代码的示例 。
对于Java ReentrantLock而言, 他的名字就可以看出是一个可重入锁,其名字是Re entrant Lock重新进入锁 。
对于Synchronized而言,也是一个可重入锁 。可重入锁的一个好处是可一定程度避免死锁 。
synchronized void setA() throws Exception{
Thread.sleep(1000);
setB();
}
synchronized void setB() throws Exception{
Thread.sleep(1000);
}
上面的代码就是一个可重入锁的一个特点,如果不是可重入锁的话,setB可能不会被当前线程执行 , 可能造成死锁 。
三、独享锁/共享锁
独享锁是指该锁一次只能被一个线程所持有 。
共享锁是指该锁可被多个线程所持有 。
对于Java
ReentrantLock而言,其是独享锁 。但是对于Lock的另一个实现类ReadWriteLock,其读锁是共享锁 , 其写锁是独享锁 。

推荐阅读