回首昨日
一、2019/2/25问题
(多选题)截止到jdk 1.8版本,java并发框架支持的锁有以下哪些?
A.排他锁
B.读写锁
C.乐观锁
D.X锁
E.自旋锁
二、选项分析
因为锁的种类和内容太多,我们就根据选项来初步认识和了解一些锁。
A.排它锁
简称X锁,又称为写锁,独占锁,是一种基本的锁类型。
1.定义:
若事务A对数据对象B加上X锁,则只允许A读取和修改B,其他任何事务都不能再对B加任何类型的锁,直到A释放B上的锁。这就保证了其他事务在A释放B上的锁之前不能在读取和修改B
2.结论:
A、D其实为同一种锁,这种锁多用于数据库中,因此并不是java并发框架支持的锁,故A、D均不为正确答案
B.读写锁
1.相关知识:
java.util.concurrent.locks.ReentrantReadWriteLock就和从它的英文翻译那样就是读写锁
reentrant也就是可重入的意思,所以它同时也是可重入锁
对于ReentratLock、Synchronized这样的排他锁而言,他们同一时刻只允许一个线程进行访问,而读写锁在同一时刻允许多个读写线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞
这是由于读和读之间并不对数据的完整性造成破坏,所以读写锁允许多个线程同时读,但是读写操作、写写操作之间仍然要相互等待和持有锁。
2.结论:
B选项明确在包中可以找到,所以正确
C.乐观锁
1.相关知识:
从锁的设计理念的宏观上来进行大的分类,所有的锁只有两类,即乐观锁和悲观锁
悲观锁:
悲观锁就是悲观的思想,总认为线程操作是都是要进行写操作,所以每次读写操作时都上锁,别的线程想要读写这个数据就会阻塞(block),直到拿到锁,java中的Synchronized就是典型的悲观锁
乐观锁:
那么如同悲观锁,乐观锁也就是一种乐观的思想,就是线程总认为读多写少,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候就判断在这段过程中有没有别人更新过这个数据。通过先读当前版本号,然后加锁操作,完成后对比是否和开始读到的版本号一样,一样就更新,如果不一样就重复之前的操作。
java通过CAS(Compare and Swap)来进行实现,就如同字面意思一样比较和交换,java.util.concurrent.atomic包下的原子类都是基于CAS实现的。
2.结论:
C选项正确
D.X锁
A选项中已说明过,不再赘述
E.自旋锁
1.相关知识:
英文名:Spin lock
当进程A一直占有者资源,进程B想要获取资源,却拿不到时,通常就会有两种情况:
1.B没有拿到,进入了阻塞,这种就是互斥锁
2.B没有拿到,不进入阻塞,但是一直循环的去看A占资源的锁是否可以拿到,这种不停试图获取锁的锁也就是自旋锁。
当锁使用者保持锁的时间比较短的情况下,自旋锁的执行效率就要远高于互斥锁,这也就是使用自旋锁的意义所在。
同样是在java.util.concurrent.atomic的AtomicInteger中就使用到了unsafe的方法,也就是使用到了自旋锁的方式。
2.结论:
E选项正确
立足今日
三、2019/2/26 问题
之前的问题都难度比较高,带来的反馈也不是很好,所以从以后开始计划一期难题一期容易的题,满足各种水平的小伙伴的需要,大家有什么好的建议和意见也可以再留言区表达自己的想法,我们都会慎重考虑。
那么今天就是一道比较简单的问题,希望大家夯实基础。
public static void main(String[] args) {
int a = '1';
System.out.println(a);
}
请问上述程序输出的结果是什么?
虽然题目很简单但是还是蛮有意思的,希望大家能有所得
展望未来
小伙伴们对题目和扩展有什么想法可以在群里分享或者公众号下方留言一起讨论哦,小刀和小伙伴在学习群里等你来一起监督学习哦,坚持!加油!
进群请加小刀微信: best396975802
END
QQ群:661749608
微信群请点击公众号菜单进微信群
文字/天堂
排版/花音
你点的每个赞,我都认真当成了喜欢