redis队列实现高并发下数据ID读取
id数据预生成
id数据预生成:根据业务逻辑,预生成ID数据,通过redis队列存储,在id被取出的过程中,选取时间节点,继续生产ID并存入队列,这样就保证队列中始终有数据(秒杀系统也可以使用这套逻辑,只是秒杀系统的队列数据不再增加)
id数据读取
通过redis单线程特性及队列特性,通过redis客户端Jedis读取队列中的id(LPOP/RPOP 操作返回队列一端数据并从队列中删除数据)
测试代码
放入测试数据
public class QueueOpt{
public static void main(String[] args) {
// JedisPoolConfig config = new JedisPoolConfig();
// config.setMaxTotal(4);
// config.setMaxIdle(4);
// JedisPool pool = new JedisPool(config, "192.168.222.169",6379);
// Jedis jedis = pool.getResource();
Jedis jedis= new Jedis("192.168.222.188",6379);
for (int i=0;i<676;i++){
jedis.lpush("task-queue",String.valueOf(i));
}
}
测试类
public class test{
public static void main(String[] args) {
JedisPoolConfig config= new JedisPoolConfig();
config.setMaxTotal(1000);
config.setMaxIdle(1000);
config.setMaxWaitMillis(50000);
JedisPool pool= new JedisPool(config, "192.168.222.188",6379);
ExecutorService executorService=Executors.newFixedThreadPool(1000);
for (int i= 0; i< 1000; i++) {
executorService.execute(new IdGenerateThread(pool,i));
}
}
线程类
public class IdGenerateThreadimplements Runnable{
private Jedisjedis;
private int i;
public IdGenerateThread(JedisPoolpool,int i){
this.jedis = pool.getResource();
this.i = i;
}
@Override
public void run() {
String key= jedis.lpop("task-queue");
System.out.println("线程="+this.i + " key="+key);
}
}