并发锁的学习

锁的定义

锁是用来协调多个线程并发访问同一共享资源时带来的安全问题,频繁用锁必然会带来性能问题,但不用锁又会造成安全问题

1)从性能上分:乐观锁和悲观锁

  • 乐观锁:CAS自旋锁,是非常经典的乐观锁,并发性能比较好,但是自旋会造成很大的开销,悲观的认为当前环境下并发情况不是很很严重,任务提交时才才判断是否冲突

  • 悲观锁:悲观的认为当前环境下并发情况是很严重的,所有的任务在执行时都要加上锁,保证了安全型,失去了并发性,并发性能差

    乐观锁:无锁,在数据提交时才去判断是否发生冲突,version

    悲观锁:每次访问数据时,都需要加锁

2)从数据库操作的类型上划分

读锁和写锁,其都是悲观锁

  • 读锁(共享锁):对读取同一行数据的并发来说,是可以同时进行的,但是写不行

  • 写锁(排它锁):在加写锁之后释放锁之前,其他的所有操作都不能进行

3)从数据的操作粒度上来划分

表锁和行锁

  • 表锁:对整张表进行上锁

    • mysiam默认支持表锁,多个线程并发操作时,一个线程操作myisam后其他所有操作都不能进行
    • innodb上表锁:lock table 表1 read/write/,表2 read /write
    • show open tables 查看当前会话的所有锁
    • unlock tables 释放当前会话的所有锁
  • 行锁:对表中的某一行记录进行上锁,支持并发读其是一个读锁

    • innodb支持行锁,在并发事务里,每个事务的读写删相当于上行锁

    • 上锁的开销大,加锁速度慢但是并发性更好

    • update tb_author set name=‘m’ where id=1

    • select * from tb_author where id=1 for update

AQS

AQS的理解

抽象队列同步器,其是并发包中的基础组件,用来实现各种锁,ReentrantLock底层由其实现包括 state变量,等待队列,加锁线程三个核心内容

实现原理:初始时state=0,加锁线程为null,线程1加锁后利用CAS判断state递增是否成功若成功加锁队列由null变为线程1,如果此时线程2也想加锁,但是state已经被使用则其进入等待队列之中,若线程1释放锁(state递减,若state=0,则彻底释放锁加锁线程为null)则从等待队列的表头唤醒线程2,重复线程1操作,如果成功则从等待队列中出列加锁线程变为线程2

事务隔离级别

事务的隔离级别

脏读:一个事务读到另外一个事务尚未提交的数据

幻读:以相同的条件,检索以前检索过的数据,发现其他事务插入了新的数据

不可重复读:一个事务在读取后的某个时间再次去读数据发现数据改变

Read uncommit 都没解决

Read commit 只解决了脏读

repeat read 没有解决幻读

serializable 都解决,最高事务级别

CAS的理解及ABA问题

CAS(compare and sort):是乐观锁的实现方式,如果多个线程CAS更新同一个变量,只有一个线程能执行,其他线程都会失败,失败的线程可以再次尝试、有内存地址V,预期原值A,新值B,V==A则V=B否则不会执行

ABA:线程E,F同时拿到了内存地址内的变量A,但是F将变量A改成B,F执行成功E执行失败

解决:在jdk1.5后提供AtomicStampedReference解决ABA

CAS缺点:ABA问题,循环时间长,开销比较大,只能保证一个共享变量的原子操作(锁去解决),浪费cpu资源

慢sql及解决

​ 查询时没有走索引,查询时间过长导致慢sql

​ 解决:对查询性能进行优化

方法加锁和对象加锁区别

  • 方法锁:让成员变量被访问时实现同步

  • 对象锁:让实例对象之间实现同步

  • 类锁:让静态资源实现同步

多用户并发怎么解决?

使用了乐观锁或者悲观锁

  • 乐观锁:CAS自旋锁,是非常经典的乐观锁,并发性能比较好,但是自旋会造成很大的开销,悲观的认为当前环境下并发情况不是很很严重,任务提交时才才判断是否冲突

  • 悲观锁:悲观的认为当前环境下并发情况是很严重的,所有的任务在执行时都要加上锁,保证了安全型,失去了并发性,并发性能差

    乐观锁:无锁,在数据提交时才去判断是否发生冲突,version

    悲观锁:每次访问数据时,都需要加锁

分段锁的理解

优点:不同段的map都能并发执行

缺点:分成很多段时,容易造成内存空间不连续或者碎片化,操作map时竞争同一个锁的概率很小,容易造成更新等操作时间过长,分段锁性能降低

sql语句使用where时尽量不要使用哪些语法?

使用where时不要使用变量或者表达式(!=,>,<,1=1等)以及in和or会导致不走索引

MVCC理解及实现原理

mvcc:多版本并发控制,是一种解决读写冲突的无所并发机制,提高并发性能,让其并发操作数据库时,读操作不阻塞写操作,写操作不阻塞读操作,解决了脏读幻读不可重复的等隔离问题

实现原理:在表中默认创建了三个字段分别代表事务id,索引,和指向日志的指针,用排它锁锁定该行记录,将记录复制到undolog日志里面然后进行事务,若成功则提交,不成功则根据指针找到日志中存储的信息

公平锁与非公平锁?

公平锁:是指多个线程按照申请锁得顺序来获取锁 ReetrantLock(boolean),true为公平锁false为非公平锁

非公平锁:是指多个线程并不是按照申请锁得顺序来获取锁,有可能后申请锁的线程优先级高于先前申请的,在高并发情况下,有可能会造成优先级反转或者饥饿现象 Synchronized

可重入锁与不可重入锁?

可重入锁(递归锁):线程可以进入任何一个他已经拥有的锁所同步着的代码块,ReentrantLock,synchronized作用:防止死锁

不可重入锁:相反

死锁:两个或者以上的线程争夺同一共享资源的僵局,如果没有外力干涉这种局面会一直保持下去直到释放资源

class lock implements Runnable {
   

    private String lockAA;
    private String lockBB;

    public lock(String lockAA, String lockBB) {
   
        this.lockAA = lockAA;
        this.lockBB = lockBB;
    }


    @Override
    public void run() {
   
        synchronized (lockAA) {
   
            System.out.println(Thread.currentThread().getName()+"持有"+lockAA+
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值