只上代码和说明,其他的不讲了,权当做个笔记。
该代码使用了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();两个方法都使用了分布式锁。
大家先看代码,有疑问可以提出。