java MD5 并发
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 并发相关推荐
- SpringBoot实现Java高并发秒杀系统之Service层开发(二)
继上一篇文章:SpringBoot实现Java高并发秒杀系统之DAO层开发 我们创建了SpringBoot项目并熟悉了秒杀系统的表设计,下面我们将讲解一下秒杀系统的核心部分:Service业务层的开发 ...
- Java高并发秒杀API(四)之高并发优化
Java高并发秒杀API(四)之高并发优化 1. 高并发优化分析 关于并发 并发性上不去是因为当多个线程同时访问一行数据时,产生了事务,因此产生写锁,每当一个获取了事务的线程把锁释放,另一个排队线程才 ...
- Java高并发秒杀API(三)之Web层
Java高并发秒杀API(三)之Web层 1. 设计前的分析 Web层内容相关 前端交互设计 Restful规范 SpringMVC Bootstrap + jQuery 前端页面流程 详情页流程逻辑 ...
- SpringBoot、Redis轻松实现Java高并发秒杀系统笔记
秒杀项目 优极限[完整项目实战]半天带你用SpringBoot.Redis轻松实现Java高并发秒杀系统 文章目录 秒杀项目 技术栈 课程介绍 学习目标 如何设计一个秒杀系统 项目搭建 分布式会话 登 ...
- java unsafe获取指针_【实战Java高并发程序设计 1】Java中的指针:Unsafe类
是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...
- Java多线程并发技术
Java多线程并发技术 参考文献: http://blog.csdn.net/aboy123/article/details/38307539 http://blog.csdn.net/ghsau/a ...
- Java 7并发编程实战手册
2019独角兽企业重金招聘Python工程师标准>>> Java 7并发编程实战手册 本书是 Java 7 并发编程的实战指南,介绍了Java 7 并发API 中大部分重要而有用的机 ...
- cpu高 thread vm_阿里大佬总结,Java高并发必读!
作者:wxdoop 原文:https://blog.csdn.net/qq_36235098 来源:前程有光 前言 进程是计算机中程序关于某几何数据集合上的一次运行活动,是系统进行资源分配和调度的基本 ...
- Java高并发编程:活跃性危险
Java高并发程序中,不得不出现资源竞争以及一些其他严重的问题,比如死锁.线程饥饿.响应性问题和活锁问题.在安全性与活跃性之间通常存在依赖,我们使用加锁机制来确保线程安全,但是如果过度地使用加锁,则可 ...
最新文章
- C语言 学生宿舍管理系统
- python输出浮点数_Python的数据类型转换,那个很多人知道的知识,你知道吗?
- python modbus类封装_Python 中引入一个文件,模块的概念
- MySQL重温笔记-索引
- Android深度探索HAL与驱动开发—第8章
- SpringMVC自动将请求参数和入参对象的属性进行一一绑定;要求请求参数的名字和javaBean入参的对象里面的属性名是一样的||员工的增删改查案例
- 手机数控模拟器安卓版_车床模拟器2手机版下载-车床模拟器2游戏 v2.5.0安卓版_5577安卓网...
- 高并发系统之限流特技
- [Java核心技术(卷I)] - Java中的参数能做什么和不能做什么
- csp真题 202109-2非零段划分C++代码(100分)
- 机器学习之梯度下降法(GD)和坐标轴下降法(CD)
- Delphi中CoInitialize之探究
- 创建Oracle本地数据库详细步骤,Oracle-创建本地数据库
- mysql日志课程_【mysql课程七】 MySQL日志管理
- 《算法笔记》的codeup打不开怎么办
- 珍藏版创业思维导图,帮你成功创业!
- wmic java_wmic 命令用法及实例
- 高斯-马尔可夫定理(Gauss-Markov Theorem)
- 丅rust是什么意思_网红编程语言Rust到底是个什么鬼?
- 史上最牛12306抢票攻略
热门文章
- 升级php影响zabbix吗,zabbix2.0升级到zabbix3.0
- python开发小型数据库_Python开发【第十七篇】:MySQL(一)
- vue获取商品数据接口_基于 request cache 请求缓存技术优化批量商品数据查询接口...
- Codeforces Round #581 (Div. 2)
- 【CSS 】动画animation
- SQL之 UNION ALL 和UNION
- laravel静态资源
- lightoj 1031 区间dp
- 自动提醒IE6访客升级浏览器,
- MFC SDI 中 通过注册表保存当前窗体的 显示状态位置