redis的消息队列和发布订阅demo

本文介绍如何利用Redis实现消息队列,包括生产者与消费者的代码示例,通过具体应用场景展示了如何有效解耦通信双方,提高系统并发处理能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前做online judge的时候用mysql+时间戳做消息队列,现在redis提供了一种现成的消息队列的模式,使用redis队列可以直接模拟消息通信的方式,在将并发转化为非并发时非常有用,同时通信的双方不需要关注彼此的信息,实现解耦合。比如用户提交了代码,我后台往消息队列压入题号,用户号,提交号,剩下的就交给判题脚本处理,判题脚本不需要了解其他信息,同时后台也不需要等待判题脚本执行结束,而是直接返回,避免了长时间占用连接。而判题脚本则是不停地从队列中取信息,并进行判题操作,同时及时更细数据库信息,标记此次判题的结果。

代码需要导入jedis的包.

producer.java(生产者)

package redis;


import redis.clients.jedis.Jedis;

public class producer implements Runnable{
  Jedis jedis=null;
   public producer(){
	jedis=new Jedis("127.0.0.1",6379);
   }
   public void run(){//生产者不停生产
	 while(true){
		String temp=String.valueOf((int)(Math.random()*1000));
		jedis.lpush("redis-test2",temp);//创造内容 
		System.out.println("放入元素"+temp);
	    try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			System.out.println("生产者产生物品失败");
			e.printStackTrace();
		}
	 }
   }
  
}
consumer.java(消费者)
package redis;

import java.util.List;

import redis.clients.jedis.Jedis;

public class consumer implements Runnable{
	Jedis jedis=null;
	public consumer(){
		jedis=new Jedis("127.0.0.1",6379);
	}
	@Override
	public void run(){//不停地消费物品
		while(true){
		List<String>list=jedis.brpop(1,"redis-test2"); 
		System.out.println("取出元素:"+list);//第一个参数代表阻塞几秒钟如果队列仍未空,则返回null,如果为0代表队列为空则始终阻塞着
		if (list!=null){//返回结果是一个列表如果不为空,下标0是队列名,下标1是取出的元素,如果为空是null
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
		}
	}
	public static void main(String[] args) {
		consumer c=new consumer();
		producer p=new producer();
		Thread t1=new Thread(c);
		t1.start();
		Thread t2=new Thread(p);
		t2.start();
	}

}
使用发布/订阅模式,注意订阅是个阻塞方法,需要开启个线程单独处理

producer2.java(发布)

package redis;

import redis.clients.jedis.Jedis;

public class producer2 implements Runnable{
    String source=null;
    Jedis jedis=null;
    public producer2(String source){
        this.source=source;
        jedis=new Jedis("127.0.0.1",6379);
    }
    @Override
    public void run(){
    
        while(true){
            String temp=String.valueOf((int)(Math.random()*1000));
            System.out.println("准备公布数字"+temp);
            jedis.publish(source,temp);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("发布出问题了");
                e.printStackTrace();
            }
        }
    }
   public static void main(String[] args) {
    consumer2 m=new consumer2("redis_chat");
    Thread t=new Thread(m);
    t.start();
    producer2 p=new producer2("redis_chat");
    Thread t2=new Thread(p);
    t2.start();
}
}



订阅(consumer2.java)

package redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class consumer2 implements Runnable{
	String source=null;
	Jedis jedis=null;
	JedisPubSub jedispubsub=null;
    public consumer2(String source){
    this.source=source;
    jedis=new Jedis("127.0.0.1",6379);
    jedispubsub=new JedisPubSub() {
    @Override
	public void onPMessage(String arg0, String arg1, String arg2) {
		
		
	}

	@Override
	public void onPSubscribe(String arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPUnsubscribe(String arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onSubscribe(String arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onUnsubscribe(String arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMessage(String arg0, String arg1) {
		System.out.println("获得信息:"+arg0+arg1);
		
	}
};
}   
    @Override
    public void run(){
    	jedis.subscribe(jedispubsub,source);
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值