Java MessageDigest.getInstance返回的实例非线程安全

问题

在当前的性能管理系统中,系统会通过Java自带的MD5 Digest为性能指标生成一个固定的列名。
但是在测试的过程中,总是会发现有些指标生成列名失败,或者列名相同。

定位及原因

生成列名代码大概如下

    private static volatile MessageDigest md5MessageDigest = null;
    
    public static String getField(String value) throws NoSuchAlgorithmException {
        if (md5MessageDigest == null) {
            md5MessageDigest = MessageDigest.getInstance("MD5");
        }
        
        byte[] digestBytes = md5MessageDigest.digest(value.getBytes(StandardCharsets.UTF_8));
        
        return toField(digestBytes);
    }
    
    public static String toField(byte[] digestBytes) {
        // 实际生成比下面的复杂,仅为了演示。
        return "ind_" + String(digestBytes, StandardCharsets.UTF_8);
    }

MessageDigest对应的MD5 Digest实例包含了个多个非静态变量,不加锁时使用同个MD5 Digest会出现多线程问题。
系统的性能指标一般是通过Excel一次性导入,导入是并发的,所以会引发上面的问题。

解决方法

每次使用MessageDigest.getInstance获取唯一的MD5 Digest。

    public static String getField(String value) throws NoSuchAlgorithmException {
        MessageDigest md5MessageDigest = MessageDigest.getInstance("MD5");

        byte[] digestBytes = md5MessageDigest.digest(value.getBytes(StandardCharsets.UTF_8));

        return toField(digestBytes);
    }

    public static String toField(byte[] digestBytes) {
        // 实际生成比下面的复杂,仅为了演示。
        return "ind_" + String(digestBytes, StandardCharsets.UTF_8);
    }
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 30,317评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,757评论 1 32
  • 1、不安全的随机数生成,在CSRF TOKEN生成、password reset token生成等,会造成toke...
    nightmare丿阅读 4,010评论 0 1
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 32,356评论 2 89
  • 他醉倒躺在天台 雨夜拍打着影子 喃喃的轻数流星 回忆着遗忘时光 他和她相恋很久 见证了成长与迷茫 以为能相守很久 ...
    十十十三阅读 239评论 0 0

友情链接更多精彩内容