Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992)。

查看MessageDigest源码

public void update(byte[] input) {engineUpdate(input, 0, input.length);state = IN_PROGRESS;
}

可以看到这里调用了engineUpdate方法,此方法进行一个更新操作。

然后state属性的状态就被改变了,表明当前计算正在处理过程中。

state默认属性

private int state = INITIAL;

然后需要调用MessageDigest.digest()方法计算哈希值

 

public byte[] digest() {/* Resetting is the responsibility of implementors. */byte[] result = engineDigest();state = INITIAL;return result;
}

到这里已经完成了MD5值的计算,state属性恢复初始状态,如果想要重用MessageDigest对象,还需要调用MessageDigest.reset()方法进行重置,以免这次计算数据会对下一次的计算造成影响,从而导致计算结果错误。

而我所遇到的问题就是,在MessageDigest在多线程的环境下,Thread-1的计算还没有完成的情况下,Thread-2又开始使用该MessageDigest对象进行下一次的计算,Thread-2修改了MessageDigest的状态,Thread-1使用被修改过后的MessageDigest进行计算,从而导致了计算结果错误。

解决方案有两个:

1、加锁来共享同一个MessageDigest;

public class MD5 {
private static final byte[] ToHex_ =
{ '0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f'
};
private MessageDigest md5_ = null;
static private MessageDigest Md5_;
static
{
try { Md5_ = MessageDigest.getInstance("MD5");} // MD5 is supported
catch ( NoSuchAlgorithmException e ) {}; // safe to swallow
};public MD5()
{
try { md5_ = MessageDigest.getInstance("MD5");} // MD5 is supported
catch ( NoSuchAlgorithmException e ) {}; // safe to swallow
}
/**
*
*/
public static synchronized String Digest(byte[] dataToHash)
{
Md5_.update(dataToHash, 0, dataToHash.length);
return HexStringFromBytes( Md5_.digest() );
}
/**
* Non-threadsafe MD5 digest (hashing) function
*/
public String digest(byte[] dataToHash)
{
md5_.update(dataToHash, 0, dataToHash.length);
return HexStringFromBytes( md5_.digest() );
}
private static String HexStringFromBytes(byte[] b)
{
byte [] hex_bytes = new byte[ b.length * 2 ];
int i,j=0;
for (i=0; i < b.length; i++)
{
hex_bytes[j] = ToHex_[ ( b[i] & 0xF0 ) >> 4 ] ;
hex_bytes[j+1] = ToHex_[ b[i] & 0xF ];
j+=2;
}
return new String( hex_bytes );
}
}

  

2、每次新创建一个MessageDigest;

class  MD5_test {  public   final   static  String MD5(String s) {  char  hexDigits[] = {  '0' ,  '1' ,  '2' ,  '3' ,  '4' ,  '5' ,  '6' ,  '7' ,  '8' ,  '9' ,  'a' ,  'b' ,  'c' ,  'd' ,  'e' ,  'f'  };  try  {  byte [] strTemp = s.getBytes();  MessageDigest mdTemp = MessageDigest.getInstance("MD5" );  mdTemp.update(strTemp);  byte [] md = mdTemp.digest();  int  j = md.length;  char  str[] =  new   char [j *  2 ];  int  k =  0 ;  for  ( int  i =  0 ; i < j; i++) {  byte  byte0 = md[i];  str[k++] = hexDigits[byte0 >>> 4  &  0xf ];  str[k++] = hexDigits[byte0 & 0xf ];  }  return   new  String(str);  } catch  (Exception e) {  return   null ;  }  }  public   static   void  main(String[] args) {  // MD5_Test aa = new MD5_Test();   System.out.print(MD5_test.MD5("a" ));
//  System.out.print(MD5_test.MD5("%7B%7DAHRCU" ));  }
}

  

这两种方案都可解决并发问题。

 

转载于:https://www.cnblogs.com/xujishou/p/8044339.html

java MD5 并发相关推荐

  1. SpringBoot实现Java高并发秒杀系统之Service层开发(二)

    继上一篇文章:SpringBoot实现Java高并发秒杀系统之DAO层开发 我们创建了SpringBoot项目并熟悉了秒杀系统的表设计,下面我们将讲解一下秒杀系统的核心部分:Service业务层的开发 ...

  2. Java高并发秒杀API(四)之高并发优化

    Java高并发秒杀API(四)之高并发优化 1. 高并发优化分析 关于并发 并发性上不去是因为当多个线程同时访问一行数据时,产生了事务,因此产生写锁,每当一个获取了事务的线程把锁释放,另一个排队线程才 ...

  3. Java高并发秒杀API(三)之Web层

    Java高并发秒杀API(三)之Web层 1. 设计前的分析 Web层内容相关 前端交互设计 Restful规范 SpringMVC Bootstrap + jQuery 前端页面流程 详情页流程逻辑 ...

  4. SpringBoot、Redis轻松实现Java高并发秒杀系统笔记

    秒杀项目 优极限[完整项目实战]半天带你用SpringBoot.Redis轻松实现Java高并发秒杀系统 文章目录 秒杀项目 技术栈 课程介绍 学习目标 如何设计一个秒杀系统 项目搭建 分布式会话 登 ...

  5. java unsafe获取指针_【实战Java高并发程序设计 1】Java中的指针:Unsafe类

    是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...

  6. Java多线程并发技术

    Java多线程并发技术 参考文献: http://blog.csdn.net/aboy123/article/details/38307539 http://blog.csdn.net/ghsau/a ...

  7. Java 7并发编程实战手册

    2019独角兽企业重金招聘Python工程师标准>>> Java 7并发编程实战手册 本书是 Java 7 并发编程的实战指南,介绍了Java 7 并发API 中大部分重要而有用的机 ...

  8. cpu高 thread vm_阿里大佬总结,Java高并发必读!

    作者:wxdoop 原文:https://blog.csdn.net/qq_36235098 来源:前程有光 前言 进程是计算机中程序关于某几何数据集合上的一次运行活动,是系统进行资源分配和调度的基本 ...

  9. Java高并发编程:活跃性危险

    Java高并发程序中,不得不出现资源竞争以及一些其他严重的问题,比如死锁.线程饥饿.响应性问题和活锁问题.在安全性与活跃性之间通常存在依赖,我们使用加锁机制来确保线程安全,但是如果过度地使用加锁,则可 ...

最新文章

  1. C语言 学生宿舍管理系统
  2. python输出浮点数_Python的数据类型转换,那个很多人知道的知识,你知道吗?
  3. python modbus类封装_Python 中引入一个文件,模块的概念
  4. MySQL重温笔记-索引
  5. Android深度探索HAL与驱动开发—第8章
  6. SpringMVC自动将请求参数和入参对象的属性进行一一绑定;要求请求参数的名字和javaBean入参的对象里面的属性名是一样的||员工的增删改查案例
  7. 手机数控模拟器安卓版_车床模拟器2手机版下载-车床模拟器2游戏 v2.5.0安卓版_5577安卓网...
  8. 高并发系统之限流特技
  9. [Java核心技术(卷I)] - Java中的参数能做什么和不能做什么
  10. csp真题 202109-2非零段划分C++代码(100分)
  11. 机器学习之梯度下降法(GD)和坐标轴下降法(CD)
  12. Delphi中CoInitialize之探究
  13. 创建Oracle本地数据库详细步骤,Oracle-创建本地数据库
  14. mysql日志课程_【mysql课程七】 MySQL日志管理
  15. 《算法笔记》的codeup打不开怎么办
  16. 珍藏版创业思维导图,帮你成功创业!
  17. wmic java_wmic 命令用法及实例
  18. 高斯-马尔可夫定理(Gauss-Markov Theorem)
  19. 丅rust是什么意思_网红编程语言Rust到底是个什么鬼?
  20. 史上最牛12306抢票攻略

热门文章

  1. 升级php影响zabbix吗,zabbix2.0升级到zabbix3.0
  2. python开发小型数据库_Python开发【第十七篇】:MySQL(一)
  3. vue获取商品数据接口_基于 request cache 请求缓存技术优化批量商品数据查询接口...
  4. Codeforces Round #581 (Div. 2)
  5. 【CSS 】动画animation
  6. SQL之 UNION ALL 和UNION
  7. laravel静态资源
  8. lightoj 1031 区间dp
  9. 自动提醒IE6访客升级浏览器,
  10. MFC SDI 中 通过注册表保存当前窗体的 显示状态位置