前言

  Redis作为缓存还是相当不错的,一定程度上缓解了数据库的IO操作,具体不多说,具体网上查找资料。

实战

不多说,直接上代码。

第一步:所需要的依赖

<!-- redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.8.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>

第二步:Redis配置文件及其相关文件

公用参数配置

#============================#
#==== Redis settings ====#
#============================#
#redis 服务器 IP
redis.host=127.0.0.1
#redis 服务器端口
redis.port=6379
#redis 密码
redis.pass= #redis 支持16个数据库(相当于不同用户)可以使不同的应用程序数据彼此分开同时又存储在相同的实例上
redis.dbIndex=0
#redis 缓存数据过期时间单位秒
redis.expiration=3000
#控制一个 pool 最多有多少个状态为 idle 的jedis实例(连接池中空闲的连接数)
redis.maxIdle=300
redis.minIdle=5
#控制一个 pool 可分配多少个jedis实例(连接池中最大连接数)
redis.maxActive=600
#当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
redis.maxWait=1000
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
redis.testOnBorrow=true

方法一

采取手动配置Redis缓存,一定要记得开启缓存

spring-redis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <description>redis 相关类 Spring 托管</description> <!-- 开启缓存 -->
<cache:annotation-driven /> <!--载入 redis 配置文件-->
<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/> <!-- 配置 JedisPoolConfig 实例 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}"/>
<property name="minIdle" value="${redis.minIdle}"/>
<property name="maxTotal" value="${redis.maxActive}"/>
<property name="maxWaitMillis" value="${redis.maxWait}"/>
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean> <!-- 配置JedisConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.pass}"/>
<property name="database" value="${redis.dbIndex}"/>
<property name="poolConfig" ref="poolConfig"/>
</bean> <!-- SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
就是因为序列化策略的不同,即使是同一个key用不同的Template去序列化,结果是不同的。所以根据key去删除数据的时候就出现了删除失败的问题。
-->
<!-- redis 序列化策略 ,通常情况下key值采用String序列化策略, -->
<!-- 如果不指定序列化策略,StringRedisTemplate的key和value都将采用String序列化策略; -->
<!-- 但是RedisTemplate的key和value都将采用JDK序列化 这样就会出现采用不同template保存的数据不能用同一个template删除的问题 -->
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<!-- <property name="valueSerializer" ref="stringRedisSerializer" /> value值如果是对象,这不能用stringRedisSerializer,报类型转换错误-->
<!-- <property name="valueSerializer">
hex(十六进制)的格式
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property> -->
<property name="valueSerializer">
<!-- json的格式,要注意实体属性名有没有‘_’,如user_name,有的话要加注解 ,@JsonNaming会将userName处理为user_name
@JsonSerialize
@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
-->
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
</bean> <!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!-- 这里可以配置多个redis -->
<bean class="com.only.mate.utils.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="default" />
</bean>
<bean class="com.only.mate.utils.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="common" /> <!-- common名称要在类或方法的注解中使用 -->
</bean>
<bean class="com.only.mate.utils.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="user" /> <!-- common名称要在类或方法的注解中使用 -->
</bean>
</set>
</property>
</bean>
<!-- 配置RedisCacheManager -->
<!-- <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redisTemplate" />
<property name="defaultExpiration" value="${redis.expiration}" />
</bean> -->
<!-- 配置RedisCacheConfig -->
<!-- <bean id="redisCacheConfig" class="com.only.mate.utils.RedisCacheConfig">
<constructor-arg ref="jedisConnectionFactory"/> <constructor-arg ref="redisTemplate"/>
<constructor-arg ref="redisCacheManager"/> </bean> -->
</beans>

RedisCache.java

package com.only.mate.utils;

import java.util.concurrent.Callable;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer; /**
* 仔细需要写redis缓存的key和value的序列化操作
* 此处还可做拓展:
* 1.存储的时候判断该key值是否已经存在
* 2.读取的时候判断key值是否存在
* 3.拿取数据的时候判断有没有失效
* @ClassName: RedisCache
* @Description: TODO
* @author OnlyMate
* @date 2017年11月24日 下午3:08:55
*/
@SuppressWarnings({ "unchecked"})
public class RedisCache implements Cache { private RedisTemplate<String, Object> redisTemplate;
private String name; private RedisSerializer<Object> keySerializer;
private RedisSerializer<Object> valueSerializer; public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate;
} public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
keySerializer = (RedisSerializer<Object>) redisTemplate.getKeySerializer();
valueSerializer = (RedisSerializer<Object>) redisTemplate.getValueSerializer();
} public void setName(String name) {
this.name = name;
} @Override
public String getName() {
// TODO Auto-generated method stub
return this.name;
} @Override
public Object getNativeCache() {
// TODO Auto-generated method stub
return this.redisTemplate;
} @Override
public ValueWrapper get(Object key) {
// TODO Auto-generated method stub
System.out.println("get key");
final String keyf = key.toString();
Object object = null;
object = redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key = keySerializer.serialize(keyf);
byte[] value = connection.get(key);
if (value == null) {
return null;
}
return valueSerializer.deserialize(value);
}
});
return (object != null ? new SimpleValueWrapper(object) : null);
} @Override
public void put(Object key, Object value) {
// TODO Auto-generated method stub
System.out.println("put key");
final String keyf = key.toString();
final Object valuef = value;
final long liveTime = 86400;
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
byte[] keyb =keySerializer.serialize(keyf);
// byte[] valueb = toByteArray(valuef);
byte[] valueb = valueSerializer.serialize(valuef);
connection.set(keyb, valueb);
if (liveTime > 0) {
connection.expire(keyb, liveTime);
}
return 1L;
}
});
} /**
* 此处写死了序列化,无法用xml中定义redisTemplate的key和value对应的序列化
* Title: evict
* @see org.springframework.cache.Cache#evict(java.lang.Object)
*/
/*private byte[] toByteArray(Object obj) {
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray();
oos.close();
bos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return bytes;
} private Object toObject(byte[] bytes) {
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
obj = ois.readObject();
ois.close();
bis.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return obj;
}*/ @Override
public void evict(Object key) {
// TODO Auto-generated method stub
System.out.println("del key");
final String keyf = key.toString();
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.del(keyf.getBytes());
}
});
} @Override
public void clear() {
// TODO Auto-generated method stub
System.out.println("clear key");
redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
connection.flushDb();
return "ok";
}
});
} @Override
public <T> T get(Object key, Class<T> type) {
// TODO Auto-generated method stub
return null;
} @Override
public ValueWrapper putIfAbsent(Object key, Object value) {
// TODO Auto-generated method stub
return null;
} @Override
public <T> T get(Object key, Callable<T> valueLoader) {
// TODO Auto-generated method stub
return null;
} }

方法二

采用注解的形式开启缓存

spring-redis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <description>redis 相关类 Spring 托管</description> <!--载入 redis 配置文件-->
<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/> <!-- 配置 JedisPoolConfig 实例 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}"/>
<property name="minIdle" value="${redis.minIdle}"/>
<property name="maxTotal" value="${redis.maxActive}"/>
<property name="maxWaitMillis" value="${redis.maxWait}"/>
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean> <!-- 配置JedisConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.pass}"/>
<property name="database" value="${redis.dbIndex}"/>
<property name="poolConfig" ref="poolConfig"/>
</bean> <!-- SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
就是因为序列化策略的不同,即使是同一个key用不同的Template去序列化,结果是不同的。所以根据key去删除数据的时候就出现了删除失败的问题。
-->
<!-- redis 序列化策略 ,通常情况下key值采用String序列化策略, -->
<!-- 如果不指定序列化策略,StringRedisTemplate的key和value都将采用String序列化策略; -->
<!-- 但是RedisTemplate的key和value都将采用JDK序列化 这样就会出现采用不同template保存的数据不能用同一个template删除的问题 -->
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<!-- <property name="valueSerializer" ref="stringRedisSerializer" /> value值如果是对象,这不能用stringRedisSerializer,报类型转换错误-->
<!-- <property name="valueSerializer">
hex(十六进制)的格式
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property> -->
<property name="valueSerializer">
<!-- json的格式,要注意实体属性名有没有‘_’,如user_name,有的话要加注解 ,@JsonNaming会将userName处理为user_name
@JsonSerialize
@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
-->
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
</bean> <!-- 配置RedisCacheManager -->
<bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redisTemplate" />
<property name="defaultExpiration" value="${redis.expiration}" />
</bean>
<!-- 配置RedisCacheConfig -->
<bean id="redisCacheConfig" class="com.only.mate.utils.RedisCacheConfig">
<constructor-arg ref="jedisConnectionFactory"/>
<constructor-arg ref="redisTemplate"/>
<constructor-arg ref="redisCacheManager"/>
</bean>
</beans>

RedisCacheConfig.java

package com.only.mate.utils;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; @Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
protected final static Logger log = LoggerFactory.getLogger(RedisCacheConfig.class); private volatile JedisConnectionFactory mJedisConnectionFactory;
private volatile RedisTemplate<String, String> mRedisTemplate;
private volatile RedisCacheManager mRedisCacheManager; public RedisCacheConfig() {
super();
log.info("RedisCacheConfig()");
} public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory, RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) {
super();
this.mJedisConnectionFactory = mJedisConnectionFactory;
this.mRedisTemplate = mRedisTemplate;
this.mRedisCacheManager = mRedisCacheManager;
log.info("RedisCacheConfig(a,b,c)");
} public JedisConnectionFactory redisConnectionFactory() {
return mJedisConnectionFactory;
} public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
return mRedisTemplate;
} public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
return mRedisCacheManager;
} @Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for (Object obj : objects) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}

第三步:在Spring的配置文件中引入spring-reids.xml

<import resource="classpath:spring-redis.xml" />

第四步:在Java代码中调用

下面注释掉的代码中,是手动缓存的操作

package com.only.mate.service.impl;

import java.io.Serializable;

import org.apache.ibatis.annotations.CacheNamespace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import com.alibaba.fastjson.JSON;
import com.only.mate.entity.User;
import com.only.mate.repository.UserMapper;
import com.only.mate.service.UserService; @Service
@Transactional
@CacheConfig(cacheNames="user")
public class UserServiceImpl implements UserService {
/*@Autowired
private UserDao userDao; @Override
public User findOne(String username) {
return userDao.getUserByUserName(username);
} @Override
public void save(User user) {
userDao.saveUser(user);
}*/
/*@Autowired
protected RedisTemplate<Serializable, Serializable> redisTemplate;*/ @Autowired
private UserMapper userMapper; @Override
@Cacheable(value="user", key="#username")
public User findOne(String username) {
User user = userMapper.getUserByUserName(username);
//使用最基本的方式
/*redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.set(redisTemplate.getStringSerializer().serialize("user." + user.getUserName()),
redisTemplate.getStringSerializer().serialize(JSON.toJSONString(user)));
return null;
}
});*/
//利用了StringRdisTemplate的特性
/*redisTemplate.opsForValue().set("user." + user.getUserName(), JSON.toJSONString(user));*/ //利用了StringRdisTemplate的特性 通过绑定的方式
/*BoundValueOperations<Serializable, Serializable> bound = redisTemplate.boundValueOps("user." + user.getUserName());
bound.append(JSON.toJSONString(user));
//bound.append(JSON.toJSONString(user));//追加,和StringBuilder的append一样功能
*/
return user;
} @Override
@CachePut(value="user", key="#user.userName")
public User save(User user) {
Integer userId = userMapper.insert(user);
if("zhangsan".equals(user.getUserName())){
throw new RuntimeException();
}
return user;
}
}

Spring与Redis的实现的更多相关文章

  1. springMVC 缓存(入门 spring+mybaties+redis一)

    使用redis之前需要咋电脑上安装redis: 使用spring+mybaties+redis的本质是扩展类   org.apache.ibatis.cache.Cache:在我们自己扩展的Cache ...

  2. spring boot redis缓存JedisPool使用

    spring boot redis缓存JedisPool使用 添加依赖pom.xml中添加如下依赖 <!-- Spring Boot Redis --> <dependency> ...

  3. spring和redis的整合-超越昨天的自己系列(7)

    超越昨天的自己系列(7) 扯淡:  最近一直在慢慢多学习各个组件,自己搭建出一些想法.是一个涉猎的过程,慢慢意识到知识是可以融汇贯通,举一反三的,不过前提好像是研究的比较深,有了自己的见解.自认为学习 ...

  4. spring data redis RedisTemplate操作redis相关用法

    http://blog.mkfree.com/posts/515835d1975a30cc561dc35d spring-data-redis API:http://docs.spring.io/sp ...

  5. Spring boot配合Spring session(redis)遇到的错误

    背景:本MUEAS项目,一开始的时候,是没有引入redis的,考虑到后期性能的问题而引入.之前没有引用redis的时候,用户登录是正常的.但是,在加入redis支持后,登录就出错!错误如下: . __ ...

  6. 【Spring】Redis的两个典型应用场景--good

    原创 BOOT Redis简介 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化. ...

  7. spring mvc Spring Data Redis RedisTemplate [转]

    http://maven.springframework.org/release/org/springframework/data/spring-data-redis/(spring-data包下载) ...

  8. Spring Data Redis简介以及项目Demo,RedisTemplate和 Serializer详解

    一.概念简介: Redis: Redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写,详细的信息在Redis官网上面有,因为我自己通过google等各种渠道去学习Redis, ...

  9. Spring Data Redis—Pub/Sub(附Web项目源码)

    一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...

  10. spring与redis集成之aop整合方案

    java使用redis缓存可以使用jedis框架,jedis操作简单,没有什么复杂的东西需要学习,网上资料很多,随便看看就会了. 将spring与redis缓存集成,其实也是使用jedis框架,只不过 ...

随机推荐

  1. 线性回归 Linear regression(3) 线性回归的概率解释

    这篇博客从一种方式推导了Linear regression 线性回归的概率解释,内容来自Standford公开课machine learning中Andrew老师的讲解. 线性回归的概率解释 在Lin ...

  2. POJ3682King Arthur's Birthday Celebration(数学期望||概率DP)

    King Arthur is an narcissist who intends to spare no coins to celebrate his coming K-th birthday. Th ...

  3. Backward Digit Sums

    FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N < ...

  4. python之wheel 包命名规则、abi 兼容和安装

    一.windows安装python包,遇见的问题 1.python3以后的版本,安装python包,可以直接使用pip安装,但是安装时偶尔报错 2.安装python源码包,如何确定自己该安装哪个版本, ...

  5. python嵌入c++

    1.去主页下载源代码项目 2.编译下载下来的项目 3.新建项目填入下面代码 // pythonIncludeTest.cpp : 定义控制台应用程序的入口点. // #include "st ...

  6. 洛谷 P3802 小魔女帕琪

    传送门 题目大意:7个东西,每个有ai个,只有选7次 把7个东西都选到了才行. 题解:7!排列数*每次选择的概率 代码: #include<iostream> #include<cs ...

  7. elixir jenkins 集成构建方式配置

    备注:    主要问题是环境变量配置的问题,解决方法是使用软连接进行解决   1. 下载软件包 wget https://github.com/elixir-lang/elixir/releases/ ...

  8. Java API 操作Zookeeper

    一.依赖 <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookee ...

  9. MUI 支付宝支付接入

    沙箱测试地址:https://openhome.alipay.com/platform/appDaily.htm 1资源下载地址:https://docs.open.alipay.com/54/106 ...

  10. LockSupport分析

    LockSupport是java.util.concurrent.locks包中的一个工具类,主要提供了一些在创建锁和同步类中用来阻塞其他线程的原始操作. 当有多个线程需要获取同一个资源的锁的时候,如 ...