编程语言
首页 > 编程语言> > 挑灯夜读——Java锁:最全锁介绍

挑灯夜读——Java锁:最全锁介绍

作者:互联网

Java最全的线程锁的介绍(不全打我)

乐观锁和悲观锁

乐观锁

在这里插入图片描述

在线程操作某一个资源时,总是认为该资源不会被其它的线程占有,只有本线程对其操作,所以不需要加锁的过程。

悲观锁

在这里插入图片描述

悲观锁,线程每次操作某一资源时,都会对其进行加锁,以防止其它线程抢夺锁。其它线程拿不到锁就会处于被阻塞的状态。

两者对比

区别点乐观锁悲观锁
不加锁,减少耗费时间加锁,保证安全
应用场景写操作极少(避免冲突)写操作多(保证安全)
实现方式原子类通过CAS乐观锁实现synchronized和ReentrantLock等

独占锁和共享锁

独占锁

获得独占锁的线程,既能修改数据,又能读取数据,操作不受限制

共享锁

获得共享锁的线程只能对其进行读操作,当线程已经拿到数据共享锁后,只能增加共享锁,独占锁无法增加。当然独占锁优先级大于共享锁。有了独占锁,共享锁无法添加。

互斥锁和读写锁

互斥锁

互斥锁一次只能有一个线程拥有,其它线程只有等待。

读写锁

读锁可以在没有写锁的情况下被多个线程同时持有,而写锁就是独占的。
相当于读锁是共享锁,而写锁是独占锁。
写锁的优先级高于读锁,并且每次读锁获取锁时,必须看到前一个写锁释放时更改的内容。

公平锁和非公平锁

公平锁:

多线程按照申请获取锁的顺序持有锁,好似银行排队办理事务的感觉。

非公平锁

该锁并不会按照先来后到的顺序获取锁,而是共同竞争,谁优先级高或者抢的快,就能获得锁。

可重入锁

public static synchronized void methodA() throws Exception{
	methodB()	
}
public static synchronized void methodB() throws Exception{
    ......//方法
}

无法放弃A,但是不放弃A由无法获得B锁,陷入左右为难,从而死锁自己的情况。宛如一个脚踏两只船的渣男/渣女。

自旋锁

通过让未获取得锁得线程产生一个自旋动作,有机会便获取锁。

分段锁

在这里插入图片描述

分段所,就是将很大一块同步块分割为很多小部分,我们无需对整个部分加锁,只需加锁需要使用得那一小块。

锁升级

无锁

偏向锁

而保存是否为偏向锁的区域为被操作对象头中的mark word中,在是否为偏向锁中添加是,偏向锁线程的ID号等,倘若有线程来操作该数据,只需要对比即可,倘若是,则直接进入。倘若不是,那么就存在竞争,进行锁升级。

轻量级锁

重量级锁:

锁优化

锁粗化:

Lock lock = new ReentrantLock();
public void menthod(){
	for(int i=0;i<100;i++){
		synchronized(lock)
		//......操作
	}
}
Lock lock = new ReentrantLock();
public void menthod(){
	synchronized(lock)
	for(int i=0;i<100;i++){
		//......操作
	}
}

锁消除

参考:

标签:加锁,Java,独占,夜读,互斥,线程,自旋,操作,挑灯
来源: https://blog.csdn.net/qq_45746068/article/details/119134527