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个线程只有一个线程拿到了任务,执行完这个任务之后,其他线程也不会再次执行这个任务

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值