新聞中心
這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
java分布式鎖和多線程一起使用
在Java中,分布式鎖是一種在多個JVM或多臺服務器上實現(xiàn)同步訪問共享資源的機制,為了解決這個問題,我們可以使用以下三種方式來實現(xiàn)分布式鎖:

專業(yè)從事網(wǎng)站設計制作、成都做網(wǎng)站,高端網(wǎng)站制作設計,微信小程序,網(wǎng)站推廣的成都做網(wǎng)站的公司。優(yōu)秀技術團隊竭力真誠服務,采用html5+CSS3前端渲染技術,響應式網(wǎng)站建設,讓網(wǎng)站在手機、平板、PC、微信下都能呈現(xiàn)。建站過程建立專項小組,與您實時在線互動,隨時提供解決方案,暢聊想法和感受。
1、基于數(shù)據(jù)庫的分布式鎖
2、基于Redis的分布式鎖
3、基于Zookeeper的分布式鎖
接下來,我們將詳細介紹這三種實現(xiàn)方式的操作方法。
基于數(shù)據(jù)庫的分布式鎖
1、創(chuàng)建一個表,用于存儲鎖信息。
CREATE TABLEdistributed_lock(idbigint(20) NOT NULL AUTO_INCREMENT,resource_idvarchar(255) NOT NULL,lock_valuevarchar(255) NOT NULL,expire_timedatetime NOT NULL, PRIMARY KEY (id), UNIQUE KEYuk_resource_id(resource_id,lock_value) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、在Java代碼中使用數(shù)據(jù)庫操作進行加鎖和解鎖:
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'"; // 根據(jù)資源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命令實現(xiàn)加鎖和解鎖:
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 { // 執(zhí)行業(yè)務邏輯 } 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秒}```
網(wǎng)站欄目:java分布式鎖和多線程一起使用
鏈接分享:http://fisionsoft.com.cn/article/dpoeppg.html


咨詢
建站咨詢
