Spring Boot整合Redisson

Redis与Redisson

什么是Redis?

Remote Dictionary Server(Redis)远程字典服务器是完全开源免费的,用C语言编写的,遵守BSD开源协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库,它也通常被称为数据结构服务器,因为值(value)可以是字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
与传统数据库不同的是 Redis 的数据是存在内存中的,所以存写速度非常快,因此 Redis被广泛应用于缓存方向。Redis为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。
Rediis 与其他 key - value 缓存产品有以下几个特点:
性能极高 – Redis读的速度是11W次/s,写的速度是81K次/s
支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
丰富的数据类型,Redis不仅仅支持简单的key-value类型的数据,同时还提供Strings, Lists, Hashes, Sets 及 Ordered Sets 等数据结构的存储。
支持数据的备份,即master-slave模式的数据备份。 Redis使用场景,查询出的数据保存到Redis中,下次查询的时候直接从Redis中拿到数据。不用和数据库进行交互。

什么是Redisson

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap,SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque,Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe,Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。 关于Redisson项目的详细介绍可以在官方网站找到。
每个Redis服务实例都能管理多达1TB的内存。

Spring Boot整合Redisson

源码地址

添加依赖

 		<dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.5.0</version>
        </dependency>

修改application.properties配置

因为是简单的demo,所以简单配置即可

server.port=8082
redisson.address=redis://192.168.1.106:6379

添加配置类

RedisConfig.java

@Configuration
public class RedisConfig {

    @Value("${redisson.address}")
    private String addressUrl;

    @Bean
    public RedissonClient getRedisson() throws Exception{
        RedissonClient redisson = null;
        Config config = new Config();
        config.useSingleServer()
                .setAddress(addressUrl);
        redisson = Redisson.create(config);

        System.out.println(redisson.getConfig().toJSON().toString());
        return redisson;
    }
}

定义redis操作接口

TestRedisService.java

@Service
public interface TestRedisService {

    RLock lock(String lockKey);

    RLock lock(String lockKey, long timeout);

    RLock lock(String lockKey, TimeUnit unit, long timeout);

    boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime);

    void unlock(String lockKey);

    void unlock(RLock lock);
}

定义操作实现类

TestRedisServiceImpl.java

@Component
public class TestRedisServiceImpl implements TestRedisService {
    // RedissonClient已经由配置类生成,这里自动装配即可
    @Autowired
    private RedissonClient redissonClient;

    // lock(), 拿不到lock就不罢休,不然线程就一直block
    @Override
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }

    // leaseTime为加锁时间,单位为秒
    @Override
    public RLock lock(String lockKey, long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(leaseTime, TimeUnit.SECONDS);
        return null;
    }

    // timeout为加锁时间,时间单位由unit确定
    @Override
    public RLock lock(String lockKey, TimeUnit unit, long timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        return lock;
    }

    @Override
    public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
    }

    @Override
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }

    @Override
    public void unlock(RLock lock) {
        lock.unlock();
    }

}

测试与验证

定义一个restcontroller,作为请求入口,在控制器中使用100个线程模拟一下获取锁的动作,然后不去释放锁,浏览器请求后查看下控制台输出情况。

@RestController
@RequestMapping("/test")
public class TestRedisController {
    @Autowired
    private TestRedisService testRedisService;
    @GetMapping("/test")
    @ResponseBody
    public void redissonTest() {
        String key = "redisson_key";
        for (int i = 0; i < 100; i++) {
            Thread t = new Thread(() -> {
                try {
                    System.err.println("=============线程开启============" + Thread.currentThread().getName());

                    /*testRedisService.lock(key,10L); //直接加锁,获取不到锁则一直等待获取锁
                      Thread.sleep(100); //获得锁之后可以进行相应的处理
                      System.err.println("======获得锁后进行相应的操作======"+Thread.
                      currentThread().getName());
                    testRedisService.unlock(key); //解锁
                      System.err.println("============================="+
                      Thread.currentThread().getName());
*/

                    boolean isGetLock = testRedisService.tryLock(key, TimeUnit.SECONDS, 5L, 10L); // 尝试获取锁,等待5秒,自己获得锁后一直不解锁则10秒后自动解锁
                    if (isGetLock) {
                        System.out.println("线程:" + Thread.currentThread().getName() + ",获取到了锁");
                        Thread.sleep(100);
                        // 获得锁之后可以进行相应的处理
                        System.err.println("======获得锁后进行相应的操作======" + Thread.currentThread().getName());
                        //distributedLocker.unlock(key);
                        System.err.println("=============================" + Thread.currentThread().getName());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            t.start();
        }
    }
}

=============线程开启============Thread-209
=============线程开启============Thread-210
=============线程开启============Thread-211
=============线程开启============Thread-212
=============线程开启============Thread-213
线程:Thread-122,获取到了锁
======获得锁后进行相应的操作======Thread-122
=============================Thread-122

122线程获得了锁,然后其他线程在等待状态。
下面将解锁代码注释去掉,查看控制台情况:

=============线程开启============Thread-213
======获得锁后进行相应的操作======Thread-130
=============================Thread-130
线程:Thread-130,获取到了锁
======获得锁后进行相应的操作======Thread-130
=============================Thread-130
======获得锁后进行相应的操作======Thread-171
=============================Thread-171
线程:Thread-171,获取到了锁
======获得锁后进行相应的操作======Thread-171
=============================Thread-171
======获得锁后进行相应的操作======Thread-155
=============================Thread-155
线程:Thread-155,获取到了锁
======获得锁后进行相应的操作======Thread-155
=============================Thread-155
======获得锁后进行相应的操作======Thread-148
=============================Thread-148
线程:Thread-148,获取到了锁
======获得锁后进行相应的操作======Thread-148
=============================Thread-148

可以发现,每次在我们设置时间过后,都会有新的线程来获得锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值