美文网首页
13 并发编程之乐观锁,悲观锁,公平锁,非公平锁

13 并发编程之乐观锁,悲观锁,公平锁,非公平锁

作者: 滔滔逐浪 | 来源:发表于2020-07-08 20:25 被阅读0次

https://github.com/wangjin123456/2020/tree/master/mayiketang/7/thread/mybatis-plus

锁的分类
悲观锁与乐观锁

公平锁与非公平锁
锁的可重入性
死锁
自旋

线程状态: 启动-运行-阻塞-结束
2.悲观锁与乐观锁:
悲观锁: 就是比较悲观。每次在执行我们的同步代码块的时候都会获取锁,如果没有获取锁的情况下,当前线程会变为阻塞状态,效率比较低。

阻塞--就绪
3,mysql中行锁机制:
Mysql中行锁概念:
在mysql中多个线程对同一行数据做写的操作时候,默认会触发航迹锁的机制。最终只有一个线程才能对行数据做写的操作,其他线程会被等待:

悲观锁的应用场景: synchronized mysql 中行锁机制。lock锁
事务的概念: 保证数据的一致性acid 原则:
Sproing 事务分类: 编程事务,声明事务
编程事务: 手动事务
声明事务: 自动事务,注解或者扫包的形式

数据库查找是否被锁的行即表:
select * from information_schema.innodb_trx t

image.png

select t.trx_mysql_thread_id from information_schema.innodb_trx t

image.png

Value的值为ON,表示autocommit开启。OFF表示autocommit关闭
set autocommit=0;---关闭

1、用 BEGIN, ROLLBACK, COMMIT来实现
BEGIN 开始一个事务
ROLLBACK 事务回滚
COMMIT 事务确认

2、直接用 SET 来改变 MySQL 的自动提交模式:
SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交

select * from information_schema.innodb_trx t
select t.trx_mysql_thread_id from information_schema.innodb_trx t
kill 768; --清理未提交的事务


select t.trx_mysql_thread_id from information_schema.innodb_trx t


show session VARIABLES  like 'autocommit'

set autocommit=0


select *  from information_schema.innodb_trx t

kill 235


UPDATE meite_user SET user_name='taotao221' where user_id=27

COMMIT

乐观锁机制:
乐观锁比较乐观,无锁,做写的操作没有锁概念,也就是不会导致我们的程序阻塞,底层通过版本号或者阀值的形式比较CAS,自旋
优点: 效率比较高 没有阻塞概念无锁机制;

缺点: 通过死循环控制 非常消耗服务器内存;

 /**
     * 乐观锁
     *
     * @return
     */
    @GetMapping("/optimisticLockUser")
    public String optimisticLock(UserEntity userEntity) {
        Long userId = userEntity.getUserId();
        // 标记该线程是否修改成功
        Integer resultCount = 0; //cas 灵活控制超时
        while (resultCount <= 0) {
            // 1.根据userid 查找到对应的VERION版本号码 获取当前数据的版本号码 VERION=1
            UserEntity dbUserEntity = userMapper.selectById(userId);
            if (dbUserEntity == null) {
                return "未查询到该用户";
            }
            // 2.做update操作的时候,放入该版本号码  乐观锁
            userEntity.setVersion(dbUserEntity.getVersion());
            resultCount = userMapper.updateById(userEntity);
        }
        return resultCount > 0 ? "success" : "fail";
    }



公平锁和非公平锁:
公平锁: 就是比较公平,先来的锁线程,根据获取锁的顺序排列获取锁。
先进来的先获得锁,后进的后获取锁,采用队列存放,先进先出原则。
非公平: 不是根据请求的顺序排列,通过争抢的形式获取锁。

package com.taotao.taotao_volatile;

import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *@author tom
 *Date  2020/7/10 0010 8:22
 *
 */
public class MayikLock  implements  Runnable{
    private  static Lock lock=new ReentrantLock(false);//false非公平锁,默认,true公平锁
    private static  int count=0;

    public static void main(String[] args) {
            long starttime=System.currentTimeMillis();
        ArrayList<Thread> thraeds=new ArrayList<>();
        for (int i = 0; i <10 ; i++) {
            Thread thread=new Thread(new MayikLock());
               thread.start();
                thraeds.add(thread);
        }
        thraeds.forEach((t)->{
            try {
                t.join();
            }catch (Exception e){
                e.getCause();
            }
        });
        long endTime=System.currentTimeMillis();
        System.out.println(endTime -starttime);
    }

    @Override
    public void run() {
        while (count<200){
           // lock.lock();;
            createCount();
          //  lock.unlock();
        }
    }

    private synchronized void createCount() {
        System.out.println(Thread.currentThread().getName()+",count:"+count);
        count++;
    }
}





独占锁: 多个线程中最终只有一个线程持有锁,其他线程都会等待。
共享锁: 多个线程可以共同一把锁lock 读写锁,例如ReentrantLock 读写锁。读读可以共享。写写互斥,写读互斥。
2个线程同时读

package com.taotao.taotao_volatile;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 *@author tom
 *Date  2020/7/10 0010 9:26
 *共享锁 读读共享,读写互斥,写写互斥
 */
public class MyTask {
    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void readlock() {
        lock.readLock().lock();
        System.out.println(">>>" + Thread.currentThread().getName() + "正在读取锁开始");
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.getCause();
        }
        System.out.println(">>>" + Thread.currentThread().getName() + "正在读取锁结束");

        lock.readLock().unlock();
    }

    public void writelock() {
        lock.writeLock().lock();
        System.out.println(">>>" + Thread.currentThread().getName() + "正在写入锁开始");
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.getCause();
        }
        System.out.println(">>>" + Thread.currentThread().getName() + "正在写入锁结束");

        lock.writeLock().unlock();
    }

    public static void main(String[] args) {
        MyTask myTask=new MyTask();
        for (int i = 0; i < 10; i++) {
           new Thread(()->{
               myTask.readlock();
           }).start();
        }
        for (int i = 0; i <10 ; i++) {
            new Thread(()-> myTask.writelock()).start();
        }
    }
}









https://github.com/wangjin123456/2020/tree/master/mayiketang/7/thread/taotao_volatile

重入锁:
只要设计锁的情况下都有可重入性。

相关文章

网友评论

      本文标题:13 并发编程之乐观锁,悲观锁,公平锁,非公平锁

      本文链接:https://www.haomeiwen.com/subject/bfrqcktx.html