java 分布式锁和多线程一起使用 - 苹果cms模板大全
  1. 苹果cms模板大全 > 流量运营 >

java 分布式锁和多线程一起使用

在Java中,分布式锁是一种在多个JVM或多台服务器上实现同步访问共享资源的机制,为了解决这个问题,我们可以使用以下三种方式来实现分布式锁:

java 分布式锁和多线程一起使用(图片来源网络,侵删)

1、基于数据库的分布式锁

2、基于Redis的分布式锁

3、基于Zookeeper的分布式锁

接下来,我们将详细介绍这三种实现方式的操作方法。

基于数据库的分布式锁

1、创建一个表,用于存储锁信息。

CREATE TABLE distributed_lock (  id bigint(20) NOT NULL AUTO_INCREMENT,  resource_id varchar(255) NOT NULL,  lock_value varchar(255) NOT NULL,  expire_time datetime NOT NULL,  PRIMARY KEY (id),  UNIQUE KEY uk_resource_id (resource_id,lock_value)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、在Java代码中使用数据库操作进行加锁和解锁:

public class DistributedLock {    private static final String LOCK_TABLE = "distributed_lock";    private static final String LOCK_COLUMN = "lock_value";    private static final String RESOURCE_ID = "resource_id";    private static final String EXPIRE_TIME = "expire_time";    public boolean lock() {        Connection connection = null;        PreparedStatement preparedStatement = null;        try {            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");            String lockValue = generateLockValue(); // 生成锁值,例如UUID            String updateSql = "INSERT INTO " + LOCK_TABLE + "(" + RESOURCE_ID + ", " + LOCK_COLUMN + ", " + EXPIRE_TIME + ") VALUES (?, ?, NOW() + INTERVAL 30 SECOND) ON DUPLICATE KEY UPDATE " + LOCK_COLUMN + " = ?, " + EXPIRE_TIME + " = NOW() + INTERVAL 30 SECOND";            preparedStatement = connection.prepareStatement(updateSql);            preparedStatement.setString(1, "resource_id"); // 设置资源ID            preparedStatement.setString(2, lockValue); // 设置锁值            preparedStatement.setString(3, lockValue); // 更新锁值和过期时间            int result = preparedStatement.executeUpdate();            return result > 0; // 如果插入成功,则表示获取锁成功        } catch (SQLException e) {            e.printStackTrace();        } finally {            if (preparedStatement != null) {                try {                    preparedStatement.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if (connection != null) {                try {                    connection.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }        }        return false; // 如果获取锁失败,则返回false    }    public void unlock() {        Connection connection = null;        PreparedStatement preparedStatement = null;        try {            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");            String deleteSql = "DELETE FROM " + LOCK_TABLE + " WHERE " + RESOURCE_ID + " = 'resource_id' AND " + LOCK_COLUMN + " = 'lock_value'"; // 根据资源ID和锁值删除记录            preparedStatement = connection.prepareStatement(deleteSql);            int result = preparedStatement.executeUpdate();            if (result > 0) { // 如果删除成功,则表示释放锁成功                System.out.println("释放锁成功");            } else { // 如果删除失败,则表示没有获取到锁,无需释放锁                System.out.println("没有获取到锁,无需释放锁");            }        } catch (SQLException e) {            e.printStackTrace();        } finally {            if (preparedStatement != null) {                try {                    preparedStatement.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if (connection != null) {                try {                    connection.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }        }    }}

基于Redis的分布式锁

1、使用Redis的SETNX命令实现加锁和解锁:

import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import java.util.concurrent.TimeUnit;import java.util.UUID;import javax.annotation.Resource;import org.springframework.stereotype.Component;import org.springframework.util.StringUtils;@Component("distributedLock") // Spring容器中的bean名称为distributedLock,以便在其他类中注入使用@Resource(name = "distributedLock") private DistributedLock distributedLock; public void doSomething() { if (distributedLock.lock()) { try { // 执行业务逻辑 } finally { distributedLock.unlock(); } } } @Override public boolean lock() { ValueOperations<String, String> valueOperations = this.redisTemplate.opsForValue(); String key = this.resourceId + this.lockValuePrefix; String lockValue = generateLockValue(); if (valueOperations.setIfAbsent(key, lockValue, this.lockExpireTime, TimeUnit.SECONDS)) { return true; } else { return false; } } @Override public void unlock() { String key = this.resourceId + this.lockValuePrefix; String lockValue = generateLockValue(); if (!StringUtils.isEmpty(lockValue)) { this.redisTemplate.delete(key); } } private String generateLockValue() { return UUID.randomUUID().toString(); } private String resourceId; private String lockValuePrefix = "lock:"; private int lockExpireTime = 30; // 默认锁定时间为30秒}```

这篇流量运营《java 分布式锁和多线程一起使用》,目前已阅读次,本文来源于酷盾,在2024-06-03发布,该文旨在普及网站运营知识,如果你有任何疑问,请通过网站底部联系方式与我们取得联系

  • 上一篇:app云服务器怎么选择路由器
  • 下一篇:云服务器连接卡怎么处理