Java常用锁:
- 重入锁
- 非重入锁
- 乐观锁
- 悲观锁
- 互斥锁
- 自旋锁
- 公平锁
- 非公平锁
- CAS无锁机制
1、什么是重入锁
重入锁是指,当执行某个加锁代码块时,代码块中的方法需要获取同一把锁,这时候可以同时使用一把锁,如下列代码
package com.nyhs.test;
public class Test01 implements Runnable {
@Override
public void run() {
set();
}
/**
* 修改数据使用synchronized(this锁)
*/
public synchronized void set() {
System.out.println("修改数据");
get();
}
/**
* 获取数据也是使用synchronized(this锁)
*/
public synchronized void get() {
System.out.println("获取数据");
}
public static void main(String[] args) {
}
}
synchronized同步函数底层使用的是当前this作为锁,这时候set()方法中需要用到this锁,但set()方法中调用了get()方法,这时候还需要使用this锁,通常来说,当锁不具备可重入性的话,当前代码被执行就会报错,因为set方法调用了this锁,而在set方法中又调用get方法,这时候get方法又需要调用this锁。
2、什么是非重入锁
在当你使用一把锁时,如果当前锁不具备重入性时,锁不会有传递性,也就是不能在同一方法中再次使用同一把锁
3、乐观锁
乐观锁的定义为:将所有操作共享数据中的线程的执行方法,都不会上锁,这样可以提高效率。
为什么要这样做呢?而且这样是否能保证共享数据的原子性,安全性?
乐观锁中,为了保证数据的原子性,安全性,其底层会使用比较算法来保证数据原子性。
当然底层并不是照我这样实现的,这里只是举个例子方便大家好理解
4、悲观锁
悲观锁,就是在进行操作的时候将某个操作进行上锁,如果某个线程抢到了这把锁,就会将其他需要这把锁的线程给sleep休眠了,只能保持一个线程进行操作,这就是悲观锁
5、互斥锁
互斥锁与悲观锁差不多,都是在进行操作的时候将未抢到锁的线程进行休眠,或者阻塞,保证数据原子性
6、自旋锁
什么是自旋锁?自旋锁与悲观锁相反,不会使其他线程挂起,而会是其他线程与乐观锁一样,重试的进行数据操作
7、什么是公平锁?
公平锁,在位于互斥锁的基础来进行修改的,当某个线程抢到锁资源时,其他线程会被挂起,然后执行完毕时再会重新进行强锁的资源,但是怎么安排哪个线程来获取锁呢?这时候就会有一个像队列一样的安排线程,是使用先进先出原则,谁先进来,谁先操作锁的资源。
8、什么是非公平锁
非公平锁,如常见的synchronized锁,属于非公平锁,当锁资源被拿到时,其他线程挂起,结束时其他线程无序列性的抢资源
9、CAS无锁机制
CAS无锁机制,如同乐观锁中的图一样,操作三个变量,一个是主内存变量,本地变量,新值。