使用RedisAtomicLong优化性能问题

目录
  • RedisAtomicLong优化性能
  • RedisAtomicLong
  • 开始优化
  • 测试代码

RedisAtomicLong优化性能

在项目中许多过这样的需求,记录留做备忘。

需要创建一个递增序列,这个序列会提供给多个应用来使用,这样就需要保持序列的原子递增。

RedisAtomicLong

spring-data-redis包中提供的,可以对数据中的Long类型进行原子性操作的类,下面是这个类的头:

/**
 * Atomic long backed by Redis. Uses Redis atomic increment/decrement and watch/multi/exec operations for CAS
 * operations.
 *  * @see java.util.concurrent.atomic.AtomicLong
 * @author Costin Leau
 * @author Thomas Darimont
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public class RedisAtomicLong extends Number implements Serializable, BoundKeyOperations<String> {

我们可以看到java.util.concurrent.atomic.AtomicLong,和java自带的atomic包一样进行原子性操作,两者不同的是:

  • AtomicLong只能在一个应用中使用
  • RedisAtomicLong可以在所有与Redis有连接的应用中使用

开始优化

应用初始化时创建RedisAtomicLong实例。

 //
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jiu.common.redis;

import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

public class RedisSequenceFactory {
    private static final Logger log = LoggerFactory.getLogger(RedisSequenceFactory.class);
    @Autowired
    private ObjectRedisTemplate<Integer> redisTemplate;

    public RedisSequenceFactory() {
    }

    public void set(String key, long value) {
        RedisAtomicLong counter = new RedisAtomicLong(key, this.redisTemplate.getConnectionFactory());
        counter.set(value);
    }

    public long generate(String key, int increment) {
        RedisAtomicLong counter = new RedisAtomicLong(key, this.redisTemplate.getConnectionFactory());
        return counter.addAndGet((long)increment);
    }

    public List<Long> generateBatch(String key, int increment, int size) {
        RedisAtomicLong counter = new RedisAtomicLong(key, this.redisTemplate.getConnectionFactory());
        long max = counter.addAndGet((long)(increment * size));
        long min = max - (long)(increment * (size - 1));
        List<Long> list = new ArrayList();
        list.add(min);

        for(int i = 1; i < size; ++i) {
            list.add(min + (long)(increment * i));
        }

        return list;
    }

    public long queryValue(String key) {
        Integer val = (Integer)this.redisTemplate.get(key);
        return val == null ? 0L : (long)val.intValue();
    }
}

测试代码

public static String tradeIdIncRedisKey = "order:orderid_inc";
     @Test
    public long generateId(){
        return redisSequenceFactory.generate(tradeIdIncRedisKey,1);
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 一篇带你解析入门LongAdder源码

    1.LongAdder由来 LongAdder类是JDK1.8新增的一个原子性操作类.AtomicLong通过CAS算法提供了非阻塞的原子性操作,相比受用阻塞算法的同步器来说性能已经很好了,但是JDK开发组并不满足于此,因为经常搞并发的请求下AtomicLong的性能是不能让人接受的. 如下AtomicLong 的incrementAndGet的代码,虽然AtomicLong使用CAS算法,但是CAS失败后还是通过无限循环的自旋锁不多的尝试,这就是高并发下CAS性能低下的原因所在.源码如下: p

  • java高并发ScheduledThreadPoolExecutor与Timer区别

    目录 正文 二者的区别 线程角度 系统时间敏感度 是否捕获异常 任务是否具备优先级 是否支持对任务排序 能否获取返回的结果 二者简单的示例 Timer类简单示例 ScheduledThreadPoolExecutor类简单示例 正文 JDK 1.5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承ThreadPoolExecutor类重用线程池实现了任务的周期性调度功能.在JDK 1.5之前,实现任务的周期性调度主要使用

  • java高并发ThreadPoolExecutor类解析线程池执行流程

    目录 摘要 核心逻辑概述 execute(Runnable)方法 addWorker(Runnable, boolean)方法 addWorkerFailed(Worker)方法 拒绝策略 摘要 ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. 今天,我们通过ThreadPoolExecutor类的源码深度解析线程池执行任务的核心流程,小伙伴们最好是打开IDEA,按照冰河说的步骤,调试下Th

  • java高并发下解决AtomicLong性能瓶颈方案LongAdder

    目录 一. LongAdder简介 二.LongAdder代码分析 (1)LongAdder的结构 (2)add方法实现 (3)add方法中longAccumulate方法的实现 三.总结 一. LongAdder简介 LongAdder类是JDK1.8新增的一个原子性操作类.上一节说到,AtomicLong通过CAS提供了非阻塞的原子性操作,相比用阻塞算法的synchronized来说性能已经得到了很大提升.在高并发下大量线程会同时竞争更新同一个原子变量,但由于只有一个线程的CAS操作会成功,

  • java高并发InterruptedException异常引发思考

    目录 前言 程序案例 问题分析 问题解决 总结 前言 InterruptedException异常可能没你想的那么简单! 当我们在调用Java对象的wait()方法或者线程的sleep()方法时,需要捕获并处理InterruptedException异常.如果我们对InterruptedException异常处理不当,则会发生我们意想不到的后果! 程序案例 例如,下面的程序代码,InterruptedTask类实现了Runnable接口,在run()方法中,获取当前线程的句柄,并在while(t

  • 分析并发编程之LongAdder原理

    目录 一.前言 二.LongAdder类的使用 三.LongAdder原理的直观理解 四.源码分析 五.与AtomicInteger的比较 六.思想的抽象 一.前言 ConcurrentHashMap的源码采用了一种比较独特的方式对map中的元素数量进行统计,自然是要好好研究一下其原理思想,同时也能更好地理解ConcurrentHashMap本身. 本文主要思路分为以下5个部分: 1.计数的使用效果 2.原理的直观图解 3.源码的细节分析 4.与AtomicInteger的比较 5.思想的抽象

  • java高并发下CopyOnWriteArrayList替代ArrayList

    目录 一.ArrayList线程不安全 二.解决ArrayList线程不安全的方案 1.使用Vector类 2.使用Collections类 3.使用CopyOnWriteArrayList类 三.CopyOnWriteArrayList 1.简介 2.主要方法源码分析 1.初始化 2.添加元素 3.获取指定位置元素 4.修改指定元素 5.删除元素 6.弱一致性的迭代器 四.总结 一.ArrayList线程不安全 在Java的集合框架中,想必大家对ArrayList肯定不陌生,单线程的情况下使用

  • tomcat性能优化(性能总览)

    1.增加JVM堆内存大小 1)JVM通常不去调用垃圾回收器,所以服务器可以更多关注处理web请求,并要求尽快完成. 2)更改文件(catalina.sh) JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+Disab

  • SQL SERVER使用表分区优化性能

    目录 1.简介 2.表分区 2.1分区范围 2.2分区键 2.3索引分区 3.创建表分区 3.1创建文件组 3.2指定文件组存放路径 3.3创建分区函数 3.4创建分区方案 3.5创建分区表 3.6创建分区索引 4.表分区的优缺点 1.简介 当一个表数据量很大时候,很自然我们就会想到将表拆分成很多小表,在执行查询时候就到各个小表去查,最后汇总数据集返回给调用者加快查询速度.比如电商平台订单表,库存表,由于长年累月读写较多,积累数据都是异常庞大的,这时候,我们可以想到表分区这个做法,降低运维和维护

  • MySQL使用索引优化性能

    目录 1.索引问题 2.索引的存储分类 3.如何使用索引 3.1使用索引 3.2存在索引但不使用索引 4.查看索引使用情况 5.两个简单实用的优化方法 5.1定期分析表和检查表 5.2定期优化表 1.索引问题 索引是数据库优化中最常用也是最重要的手段之一,通过索引通常可以帮助用户解决大多数 的SQL性能问题.本章节将对MySQL中的索引的分类.存储.使用方法做详细的介绍. 2.索引的存储分类 MyISAM存储引擎的表数据和索引是自动分开存储的,各自是独立的一个文件:InnoDB存储引擎的表数据和

  • sql server查询语句阻塞优化性能

    在生产环境下,有时公司客服反映网页半天打不到,除了在浏览器按F12的Network响应来排查,确定web服务器无故障后.就需要检查数据库是否有出现阻塞 当时数据库的生产环境中主表数据量超过2000w,子表数据量超过1亿,且更新和新增频繁.再加上做了同步镜像,很消耗资源. 这时就要新建一个会话,大概需要了解以下几点: 1.当前活动会话量有多少? 2.会话运行时间? 3.会话之间有没有阻塞? 4.阻塞时间 ? 查询阻塞的方法有很多.有sql 2000 的sp_lock, 有sql 2005及以上的d

  • sql server排查死锁优化性能

    一.概述 记得以前客户在使用软件时,有偶发出现死锁问题,因为发生的时间不确定,不好做问题的重现,当时解决问题有点棘手了.现总结下查看死锁的常用二种方式. 1.1 第一种是图形化监听: sqlserver -->工具--> sql server profiler 登录后在跟踪属性中选择如下图: 监听到的死锁图形如下图 这里的描述大致是:有二个进程 一个进程ID是96, 另一个ID是348. 系统自动kill 掉了进程ID:96,保留了进程ID:348 的事务Commit. 上面死锁是由于批量更新

  • MySQL实现批量插入以优化性能的教程

    对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长.特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久.因此,优化数据库插入性能是很有意义的. 经过对MySQL innodb的一些性能测试,发现一些可以提高insert效率的方法,供大家参考参考. 1. 一条SQL语句插入多条数据. 常用的插入语句如: INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VAL

  • ASP.NET页面优化 性能提升8倍的方法

    为了让您对优化的效果有个直观的了解,我准备了下面的测试结果截图: 测试环境: 1. Windows Server 2003 SP2 2. Viaual Studio 2008,使用自带的WebDev.WebServer.EXE运行网站程序. 3. (ThinkPad SL510):Core2 T6670 2.2GHz, 4G内存 二个红框中的数字反映了优化前后的执行时间. 数字表明:优化前后,执行时间有了8倍多的差别. 测试背景 看过了优化结果,再来介绍一下:这个测试到底是在测试什么东西? 现在

  • ASP.NET中常用的优化性能的方法

    1. 数据库访问性能优化   数据库的连接和关闭  访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池(Connection Pool)改善打开和关闭数据库对性能的影响.系统将用户的数据库连接放在连接池中,需要时取出,关闭时收回连接,等待下一次的连接请求.  连接池的大小是有限的,如果在连接池达到最大限度后仍要求创建连接,必然大大影响性能.因此,在建立数据库连接后只有在真正需要操作时才打开连接,

  • 从MySQL得到最大的优化性能

    优化是一项复杂的任务,因为它最终需要对整个系统的理解.当用你的系统/应用的小知识做一些局部优化是可能的时候,你越想让你的系统更优化,你必须知道它也越多. 因此,本章将试图解释并给出优化MySQL的不同方法的一些例子.但是记住总是有某些(逐渐变难)是系统更快的方法留着去做. 为了使一个系统更快的最重要部分当然是基本设计.你也需要知道你的系统将做这样的事情,那就是你的瓶颈. 最常见的瓶颈是: 磁盘寻道.磁盘花时间找到一个数据,用在1999年的现代磁盘其平均时间通常小于10ms,因此理论上我们能大约一

  • Web性能优化系列 10个提升JavaScript性能的技巧

    Nicholas Zakas是一位 JS 大师,Yahoo! 首页的前端主程.他是<高性能 Javascript>的作者,这本书值得每个程序员去阅读. 当谈到 JS 性能的时候,Zakas差不多就是你要找的,2010年六月他在Google Tech Talk发表了名为<Speed Up Your Javascript>的演讲. 但 Javascript 性能优化绝不是一种书面的技术,Nicholas 的技术演进列出了10条建议,帮助你写出高效的 JS 代码. 1. 定义局部变量 当

随机推荐