说说在JAVA中使用Redis,以及Redis分布锁

只上代码和说明,其他的不讲了,权当做个笔记。

该代码使用了1年多,在高并发的情况下并无问题,所以分享给大家。

package util;


import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;

import com.system.PublicParameter;



import net.sf.json.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;

public final class  RedisUtil{
    
	private static String ADDR = "XXX.XXX.X.XXX";

    
    //Redis的端口号
    private static int PORT = 6379;
    
    //访问密码
    private static String AUTH = "XXXX";
    
    //可用连接实例的最大数目,默认值为8;
    //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
    private static int MAX_ACTIVE = 800;
    
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
    private static int MAX_IDLE = 100;
    
    //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
    private static long MAX_WAIT = 50000;
    
    private static int TIMEOUT = 50000;
    
    //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
    private static boolean TEST_ON_BORROW = true;
    
    public static JedisPool jedisPool = null;
    
    /**
     * 初始化Redis连接池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDR, PORT,TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 获取Jedis实例
     * @return
     */
    public synchronized static Jedis getJedis()  
    {  
        int timeoutCount = 0;  
        while (true) // 如果是网络超时则多试几次  
        {  
            try  
            {  
                Jedis jedis = jedisPool.getResource();  
                return jedis;  
            } catch (Exception e)  
            {  
                // 底层原因是SocketTimeoutException,不过redis已经捕捉且抛出JedisConnectionException,不继承于前者  
                if (e instanceof JedisConnectionException || e instanceof SocketTimeoutException)  
                {  
                    timeoutCount++;  
                   System.out.println("getJedis timeoutCount="+timeoutCount);  
                    if (timeoutCount > 3)  
                    {  
                        break;  
                    }  
                }else  
                {  
                 
                    break;  
                }  
            }  
        }  
        return null;  
    }  
    /**
     * 释放jedis资源
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedisPool.returnResource(jedis);
        }
    }
    
    
    public static void mset(String key,String value){
    	Jedis redis = getJedis();
    	try {
    		redis.set(key, value);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jedisPool.returnResource(redis);
		}
    	
    }
    
    public static String mget(String co_make,String key){
    	Jedis redis = getJedis();
    	String value="";
    	try {
    		
        	if(key.equals("")){
        		value=redis.get(co_make);
        	}else{
        		if(redis.get(co_make)!=null){
        			 net.sf.json.JSONObject json1 = net.sf.json.JSONObject.fromObject(redis.get(co_make).toString());
        			if(json1.get(key)!=null){
	    	       		 value=json1.getString(key);
        			}
        		}
        	}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jedisPool.returnResource(redis);
		}
    	
		return setNullToBanlk(value);
    }
    
    
    
    public static String mget(String key){
    	Jedis redis = getJedis();
    	String value="";
    	try {
    		value=redis.get(key);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jedisPool.returnResource(redis);
		}
    	
		return setNullToBanlk(value);
    }
    
    public static void mdel(String key){
    	Jedis redis = getJedis();
    	try {
    		redis.del(key);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jedisPool.returnResource(redis);
		}
    	
    }
    
    
    
    
	public static String setNullToBanlk(String name) {
	    if (name == null) {
	      name = "";
	    }
	    return name != null ? name.trim() : "";
 }
	public RedisUtil() {
		
	}
	public static void main(String[] args) {
		for (int i = 0; i < 3000; i++) {
			new Thread(new Runnable() {
				
				public void run() {
					Jedis redis = getJedis();
					try {
						for (int i = 0; i < 1000; i++) {
							redis.mset("a", "1");
							System.out.println("线程1成功==="+i);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					
				}
			}).start();
		}
		
		
		
		
		
		
		
	}
	
	

}

使用的jar包:

jedis-2.7.2.jar

commons-pool2-2.2.jar

jackson-core-asl-1.6.4.jar

再说说分布锁,这个比较重要,因为在分布式架构哦的并发情况下,如果有业务需要计算金额,或者计数,就需要用到分布锁

 

package com.qh_goal;


import java.net.SocketTimeoutException;
import java.util.Collections;
import java.util.UUID;




import net.sf.json.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;

public final class  RedisUtil{

	private static String ADDR = "xxx.xxx.x.xxx";


	//Redis的端口号
	private static int PORT = 6379;

	//访问密码
	private static String AUTH = "xxxxxx";

	//可用连接实例的最大数目,默认值为8;
	//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
	private static int MAX_ACTIVE = 800;

	//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
	private static int MAX_IDLE = 100;

	//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
	private static long MAX_WAIT = 50000;

	private static int TIMEOUT = 50000;

	//在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
	private static boolean TEST_ON_BORROW = true;

	public static JedisPool jedisPool = null;
	private static DistributedLock lock = null;
	/**
	 * 初始化Redis连接池
	 */
	static {
		try {
			JedisPoolConfig config = new JedisPoolConfig();
			config.setMaxTotal(200);
			config.setMaxIdle(50);
			config.setMinIdle(8);//设置最小空闲数
			config.setMaxWaitMillis(10000);
			config.setTestOnBorrow(true);
			config.setTestOnReturn(true);
			//Idle时进行连接扫描
			config.setTestWhileIdle(true);
			//表示idle object evitor两次扫描之间要sleep的毫秒数
			config.setTimeBetweenEvictionRunsMillis(30000);
			//表示idle object evitor每次扫描的最多的对象数
			config.setNumTestsPerEvictionRun(10);
			//表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
			config.setMinEvictableIdleTimeMillis(60000);
			jedisPool = new JedisPool(config, ADDR, PORT,TIMEOUT);
			lock = new DistributedLock(jedisPool);
			System.out.println("1");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	


	

	/**
	 * 获取Jedis实例
	 * @return
	 */
	synchronized public  static Jedis getJedis()  
	{  
		int timeoutCount = 0;  
		while (true) // 如果是网络超时则多试几次  
		{  
			try  
			{  
				Jedis jedis = jedisPool.getResource();  
				return jedis;  
			} catch (Exception e)  
			{  
				// 底层原因是SocketTimeoutException,不过redis已经捕捉且抛出JedisConnectionException,不继承于前者  
				if (e instanceof JedisConnectionException || e instanceof SocketTimeoutException)  
				{  
					timeoutCount++;  
					System.out.println("getJedis timeoutCount="+timeoutCount);  
					if (timeoutCount > 3)  
					{  
						break;  
					}  
				}else  
				{  

					break;  
				}  
			}  
		}  
		return null;  
	}  
	/**
	 * 释放jedis资源
	 * @param jedis
	 */
	public static void returnResource(final Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnResource(jedis);
		}
	}
	public static void msetValue(String key,String value){
		Jedis redis = getJedis();
		try {
			redis.set(key, value);

		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			redis.close();
			redis = null;
		}

	}
	
	public static String mgetValue(String key){
		Jedis redis = getJedis();
		String value="";
		try {
			value=redis.get(key);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			redis.close();
			redis = null;
		}

		return setNullToBanlk(value);
	}

	public static void mset(String key,String value,Jedis redis){
		try {
			redis.set(key, value);

		} catch (Exception e) {
			e.printStackTrace();
		}finally{
		}

	}

	public static String mget(String co_make,String key){
		Jedis redis = getJedis();
		String value="";
		try {

			if(key.equals("")){
				value=redis.get(co_make);
			}else{
				if(redis.get(co_make)!=null){
					net.sf.json.JSONObject json1 = net.sf.json.JSONObject.fromObject(redis.get(co_make).toString());
					if(json1.get(key)!=null){
						value=json1.getString(key);
					}
				}

			}

		} catch (Exception e) {
			e.printStackTrace();
		}finally{

		}

		return setNullToBanlk(value);
	}



	public static String mget1(String key,Jedis redis){
		
		String value="";
		try {
			value=redis.get(key);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
		}

		return setNullToBanlk(value);
	}

	public static void mdel(String key){
		Jedis redis = getJedis();
		try {
			redis.del(key);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jedisPool.returnResource(redis);
		}

	}




	public static String setNullToBanlk(String name) {
		if (name == null) {
			name = "";
		}
		return name != null ? name.trim() : "";
	}
	public RedisUtil() {

	}
	 static int n = 500;
	 public static String seckill(String company_id,float value) {
		  Jedis redis = getJedis();
		  String a = "";
		 	try {
		 		 // 返回锁的value值,供释放锁时候进行判断
		 		  String indentifier = lock.lockWithTimeout("resource", 5000, 1000);
			       
			        System.out.println("REDIS----1----"+Thread.currentThread().getName() + "获得了锁");
			        a = mget1(company_id,redis);
			        mset(company_id, Float.parseFloat(a)-value+"",redis);
			        a = mget1(company_id,redis);
			        lock.releaseLock("resource", indentifier,redis);
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				redis.close();
				redis = null;
			}
			return a;
	       
	      
	       

	 }
	 
	 
	 public static String secGetValue(String company_id) {
		  Jedis redis = getJedis();
		  String value = "";
		 	try {
		 		 // 返回锁的value值,供释放锁时候进行判断
		 		  String indentifier = lock.lockWithTimeout("resource", 5000, 1000);
			       
			        System.out.println("REDIS----1----"+Thread.currentThread().getName() + "获得了锁");
			        value = mget1(company_id,redis);
			        lock.releaseLock("resource", indentifier,redis);
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				redis.close();
				redis = null;
			}
		 	return setNullToBanlk(value);
	       
	      
	       

	 }
	 
	 public static void seckill2() {
		  Jedis redis = getJedis();
		 	try {
		 		 // 返回锁的value值,供释放锁时候进行判断
		 		  String indentifier = lock.lockWithTimeout("resource", 5000, 1000);
			       
//			        System.out.println("REDIS----1----"+Thread.currentThread().getName() + "获得了锁");
//			        String a = mget1("a",redis);
//			        mset("a", n--+"",redis);
			        System.out.println("线程成功2==="+mget1("a",redis));
			        lock.releaseLock("resource", indentifier,redis);
			} catch (Exception e) {
				// TODO: handle exception
			}finally{
				redis.close();
				redis = null;
			}
	       
	      
	       

	 }
	 
	public static void main(String[] args) throws InterruptedException {
		final String uuid = UUID.randomUUID().toString();
		 Jedis redis = getJedis();
		mset("a", "0",redis);
		jedisPool.returnResource(redis);
		for (int i = 0; i < 500; i++) {
			new Thread(new Runnable() {

				public void run() {
					try {

						seckill("",1);
						seckill2();
						

					} catch (Exception e) {
						e.printStackTrace();
					}

				}
			}).start();
		}
		
		





	}

	
}

main方法中的seckill("",1); seckill2();两个方法都使用了分布式锁。

大家先看代码,有疑问可以提出。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫川琴秀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值