锁的深入
- 什么是重入锁
- 锁的种类
- 读写锁
- 悲观和乐观
- CAS无锁
- 自旋锁
- AQS
- 非公平锁
- 公平锁
- 互斥锁
- 排他锁
- 分布式锁:redis实现分布式锁。Zookeeper实现分布式锁
轻量级锁(Lock)与重量级锁(Synchronized)–可重入性(递归锁)
可重入锁就是可以循环的递归的获取到改锁
1.ReentrantLock(可重入锁)该代码不会报错
package day07;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//演示lock锁是否具备可重入性 特征,锁可以传递(方法递归进行传递)
public class Test0002 extends Thread{
Lock lock = new ReentrantLock();
@Override
public void run() {
set();
}
//synchronized 是什么时候释放锁?避免死锁
public void set(){
try {
lock.lock();
System.out.println("set 方法");
get();
}catch (Exception e){
}finally {
lock.unlock();
}
}
public void get(){
try {
lock.lock();
System.out.println("lock 可以具备可重入性-get方法");
}catch (Exception e){
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
Thread thread = new Test0002();
thread.start();
}
}
读写锁–读写分离
读锁(获取该值信息)和写锁(对该值做操作)wait notify
悲观锁和乐观锁
- 悲观锁:特征:属于重量级锁,会阻塞、会进行等待。
- 乐观锁–本质没有锁,效率比较高、无阻塞、无等待、重试。-CAS无锁机制
重点:
原子类线程安全 非阻塞、本质底层没有使用锁
原子类底层实现原理CAS无锁技术 比较
CAS: compare and swap ,即比较在交换。
它包含三个参数CAS(V,E,N):V 表示要跟新的变量,E表示预期值,N表示新值。仅当V值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。最后,CAS返回当前V的真实值。
//悲观
package day07;
//两个线程,同时操作一个全局变量,演示线程安全问题
public class Test0004 implements Runnable{
//共享的全局变量
private static int count = 1;
@Override
public void run() {
while (true){
Integer count = getCount();
System.out.println(count);
}
}
//synchronized 具有可重入、保证原子性和可见性。不能解决重排序
public synchronized Integer getCount(){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
return count++;
}
public static void main(String[] args) {
Test0004 test0004 = new Test0004();
Thread t1 = new Thread(test0004);
Thread t2 = new Thread(test0004);
t1.start();
t2.start();
}
}
乐观 -无锁机制
package day07;
import java.util.concurrent.atomic.AtomicInteger;
//两个线程,同时操作一个全局变量,演示线程安全问题
public class Test0005 implements Runnable{
// //共享的全局变量
// private static int count = 1;
AtomicInteger atomicInteger = new AtomicInteger();//线程安全
@Override
public void run() {
while (true){
Integer count = getCount();
System.out.println(count);
}
}
//synchronized 具有可重入、保证原子性和可见性。不能解决重排序
public Integer getCount(){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
//每次在做自增 i++ ;是线程安全的但是底层是没加锁
return atomicInteger.incrementAndGet();
}
public static void main(String[] args) {
Test0005 test0005 = new Test0005();
Thread t1 = new Thread(test0005);
Thread t2 = new Thread(test0005);
t1.start();
t2.start();
}
}
互斥锁与自旋锁
互斥:等待、阻塞、悲观锁
自旋锁: 属于乐观锁
公平锁与非公平锁
公平锁就是先到先得,按顺序进行,非公平锁就是不排队直接拿走,失败在说。