Java中的线程安全
什么是线程安全
线程安全指在多线程环境下,共享资源能够被多个线程安全地访问和修改,不会出现数据异常或不一致的情况。
Threadlocal
每个线程在访问该变量时,都会拷贝一个副本至本地内存,所以多线程下操作ThreadLocal变量时,各自都是在操作自己拷贝的副本,互不影响,这样自然而然就避免了线程安全问题。
Threadlocal包含一个静态内部类ThreadLocalMap。
Map里面存储线程本地对象ThreadLocal(key)和线程的变量副本(value)。
Threadlocal应用
在Spring项目中Dao层中装配的Connection肯定是线程安全的,其解决方案就是采用ThreadLocal方法,当每个请求线程使用Connection的时候, 都会从ThreadLocal获取一次,如果为null,说明没有进行过数据库连接,连接后存入ThreadLocal中,如此一来,每一个请求线程都保存有一份 自己的Connection。于是便解决了线程安全问题
Threadlocal内存溢出
线程的threadLocals放入的entry没有被及时的remove掉
volatile关键字
volatile变量每次被线程访问时,都强迫线程从主内存中重读该变量的最新值
synchronized(自动释放锁)
通过使用synchronized关键字来确保在同一时刻只有一个线程能够访问共享资源。可以应用于方法级别或代码块级别。
// 同步方法
public synchronized void synchronizedMethod() {
// 共享资源访问
}
// 同步块
public void synchronizedBlock() {
synchronized (lockObject) {
// 共享资源访问
}
}
synchronized关键字用在方法和代码块上的区别
同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁,很明显,同步方法锁的范围比较大,而同步代码块范围要小点,一般同步的范围越大,性能就越差
Lock(finally块中写unlock()手动释放锁)
lock是一个接口,手动在finally块中写unlock()以防死锁。
ReadWriteLock
Synchronized依赖JVM而Reentrantlock API
ReentrantLock
以ReentrantLock为例,state初始化为0,表示未锁定状态。A线程lock()时,会调用tryAcquire()独占该锁并将state+1。此后,其他线程在tryAcquire()时就会失败,直到A线程unlock()到state=0(即释放锁)为止,其它线程才有机会获取该锁。当然,释放锁之前,A线程自己是可以重复获取此锁的(state会累加),这就是可重入的概念。但要注意,获取多少次就要释放多少次,这样才能保证state是能回到零态的。
CountDownLatch
CountDownLatch 定义了一个计数器,和一个阻塞队列,计数器递减到0时会唤醒阻塞队列所有线程
可重入锁和不可重入锁
ReentrantLock和synchronized都是可重入锁
公平锁与非公平锁
JVM 随机就近原则分配锁的机制则称为不公平锁,非公平锁实际执行的效率要远超公平锁,除非程序有特殊需要,否则最常用非公平锁的分配机制。
非公平锁性能比公平锁高 5~10 倍,因为公平锁需要在多核的情况下维护等待队列
-Java 中的 synchronized 是非公平锁,ReentrantLock 默认的 lock()方法采用的是非公平锁(构造时提供了公平);
公平锁指的是锁的分配机制是公平的,通常先对锁提出获取请求的线程会先被分配到锁
锁升级
偏向锁
偏向锁,顾名思义,它会偏向于第一个访问锁的线程
将锁对象的状态标志位改为01,即偏向模式。然后使用CAS操作将线程的ID记录在锁对象的Mark Word中。以后该线程可以直接进入同步块,连CAS操作都不需要
轻量级锁(自旋锁)
轻量级锁采用CAS自旋锁的方式来完成加锁,轻量级锁膨胀为重量级锁的条件就是自旋达超过一定次数(默认为10
重量级锁
当后续线程尝试获取锁时,发现被占用的锁是重量级锁,则直接将自己挂起,等待将来被唤醒。在JDK1.6之前,synchronized直接加重量级锁,很明显现在得到了很好的优化。
重量级锁的特点:会让抢占锁的线程从用户态转变为内核态,其他线程试图获取锁时,都会被阻塞,只有持有锁的线程释放锁之后才会唤醒这些线程。
AQS(AbstractQuenedSynchronizer)抽象队列同步器
- state 状态
- CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列
- 获取/释放
原文链接:https://blog.csdn.net/qq_40722827/article/details/105598682
待更新、、