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

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

专业从事网站设计制作、成都做网站,高端网站制作设计,微信小程序,网站推广的成都做网站的公司。优秀技术团队竭力真诚服务,采用html5+CSS3前端渲染技术,响应式网站建设,让网站在手机、平板、PC、微信下都能呈现。建站过程建立专项小组,与您实时在线互动,随时提供解决方案,畅聊想法和感受。

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 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分布式锁和多线程一起使用
文章起源:http://www.mswzjz.com/qtweb/news34/164934.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联