控制并发数量处理数据
import redis.clients.jedis.Jedis;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.atomic.AtomicInteger;
public class InstructionProcessor {
private static final String REDIS_HOST = "localhost";
private static final int REDIS_PORT = 6379;
private static final String CONCURRENCY_COUNT_KEY = "concurrency_count:";
private static final int MAX_CONCURRENCY = 3;
private static final AtomicInteger localConcurrencyCount = new AtomicInteger(0);
public void processInstruction(String instruction) {
try (Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT)) {
String machineId = getMachineId();
String countKey = CONCURRENCY_COUNT_KEY + machineId;
// 获取 Redis 分布式锁
if (RedisDistributedLock.tryLock(jedis, countKey)) {
try {
// 检查并发计数是否超过上限
long currentCount = getCurrentCount(jedis, countKey);
if (currentCount < MAX_CONCURRENCY && localConcurrencyCount.get() < MAX_CONCURRENCY) {
// 增加并发计数
incrementCount(jedis, countKey);
localConcurrencyCount.incrementAndGet();
try {
// 处理 MySQL 数据
processMySQLData(instruction);
} finally {
// 减少并发计数
decrementCount(jedis, countKey);
localConcurrencyCount.decrementAndGet();
}
} else {
System.out.println("Concurrency limit reached, cannot process instruction.");
}
} finally {
// 释放 Redis 分布式锁
RedisDistributedLock.unlock(jedis, countKey);
}
} else {
System.out.println("Failed to acquire distributed lock.");
}
}
}
private long getCurrentCount(Jedis jedis, String key) {
String countStr = jedis.get(key);
return countStr == null ? 0 : Long.parseLong(countStr);
}
private void incrementCount(Jedis jedis, String key) {
jedis.incr(key);
}
private void decrementCount(Jedis jedis, String key) {
jedis.decr(key);
}
private String getMachineId() {
// 这里可以实现获取机器唯一标识的逻辑,例如使用 IP 地址等
return "machine_1";
}
private void processMySQLData(String instruction) {
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/your_database", "your_username", "your_password");
PreparedStatement statement = connection.prepareStatement("INSERT INTO your_table (instruction) VALUES (?)")) {
statement.setString(1, instruction);
statement.executeUpdate();
System.out.println("Processed instruction: " + instruction);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
测试代码
public class Main {
public static void main(String[] args) {
InstructionProcessor processor = new InstructionProcessor();
for (int i = 0; i < 10; i++) {
final int index = i;
new Thread(() -> {
processor.processInstruction("Instruction " + index);
}).start();
}
}
}
代码解释:
Redis 分布式锁:RedisDistributedLock 类提供了 tryLock 和 unlock 方法,用于获取和释放 Redis 分布式锁。 指令处理器:InstructionProcessor 类的 processInstruction 方法是核心处理方法,具体步骤如下:
获取 Redis 分布式锁,确保同一时刻只有一个进程可以进行并发数的检查和更新操作。 检查 Redis 中的并发计数和本地的并发计数是否超过上限。 如果未超过上限,增加并发计数,并使用 CAS 机制(AtomicInteger)更新本地并发计数。 处理 MySQL 数据。 处理完成后,减少并发计数,并释放 Redis 分布式锁。
测试代码:在 Main 类中创建 10 个线程,模拟并发处理指令的场景。