MySQL实现分布式锁

实现分布式锁的步骤:

  ① 准备两张表(两张表的主键相同,利用mysql的唯一约束实现分布式锁),一张用来存任务,另一张存任务的锁

  ② 从任务表中获取要执行任务的数据信息

  ③ 向任务锁表中插入当前任务,若插入成功,则拿到了任务锁,可以执行任务,否则就不能执行任务

创建数据库表

#   创建任务表
create table if not exists `task`(
    id bigint primary key auto_increment comment '主键',
    description varchar(100) not null comment '任务描述'
);
#   创建任务锁表
create table if not exists `task_lock`(
    id bigint primary key comment '主键',
    description varchar(100) not null comment '任务描述'
);
#   添加任务
insert into `task`
    (id, description)
values
    (1,'说句hello world');

Java实体类

任务类

public class Task {
    private Long id;
    private String description;
    /*getter setter ...*/
}

任务锁类

public class TaskLock {
    private Long id;
    private String description;
     /*getter setter ...*/
}

mapper(直接继承的mybatisplus的BaseMapper)

public interface TaskMapper extends BaseMapper<Task> {
}
public interface TaskLockMapper extends BaseMapper<TaskLock> {
}

开启5000个线程模拟5000个服务去抢这一个任务资源

@SpringBootTest
public class LockTest {
    
    @Autowired
    private TaskMapper taskMapper;
    
    @Autowired
    private TaskLockMapper taskLockMapper;

    @Test
    void test_distributeLock_mysql() throws InterruptedException {
        Runnable run = () -> {
            //  获取id为1的任务信息
            Task task = taskMapper.selectById(1);
            //  向任务锁表中插入数据,若插入成功,代表拿到了锁,可以执行任务
            TaskLock taskLock = new TaskLock();
            taskLock.setId(task.getId());
            taskLock.setDescription(task.getDescription());
            try {
                taskLockMapper.insert(taskLock);
                //  拿到锁,执行打印任务
                System.out.println("hello world!");
            }catch (Exception e){
                //  未拿到锁
            }
        };
        List<Thread>threadPool = new ArrayList<>(5000);
        for (int i = 0; i < 5000; i++) {
            Thread thread = new Thread(run);
            thread.start();
            threadPool.add(thread);
        }
        for (Thread thread : threadPool) {
            thread.join();
        }
    }
}

执行结果:7b3ccd45c0434248899040e49cbe7cb3.png

可以看到5000个线程只有一个线程拿到了任务,执行完这个任务之后,其他线程也不会再次执行这个任务

 

相关推荐

  1. Mysql实现分布式

    2024-05-25 23:22:48       22 阅读
  2. MySQL、Redis 和 Zookeeper 实现分布式方法及优缺点

    2024-05-25 23:22:48       15 阅读
  3. Zookeeper实现分布式(Zk分布式

    2024-05-25 23:22:48       16 阅读
  4. Zookeeper实现分布式

    2024-05-25 23:22:48       24 阅读
  5. Redis实现分布式

    2024-05-25 23:22:48       24 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-25 23:22:48       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-25 23:22:48       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-25 23:22:48       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-25 23:22:48       20 阅读

热门阅读

  1. 【Muduo】网络库框架模型和各模块简介

    2024-05-25 23:22:48       13 阅读
  2. C# 中的 Dictionary<TKey, TValue> 类

    2024-05-25 23:22:48       15 阅读
  3. docker system prune命令详解

    2024-05-25 23:22:48       12 阅读
  4. MySql开源闪回工具MyFlash

    2024-05-25 23:22:48       14 阅读
  5. 使用Python从网站API下载视频并转换为MP4文件

    2024-05-25 23:22:48       10 阅读
  6. Pytorch-03 数据集与数据加载器

    2024-05-25 23:22:48       13 阅读