Java并发基础2-原子操作
接上文,在并发情况下,使用了volatile关键字,能否保证多线程情况下结果的准确性?答案是不能,验证如下:
//自定义的类public static class MyTest { //类的内部成员变量num public volatile int num = 0; public void numPlusPlus() { num++; }}
主方法为
public static void main(String[] args) { MyTest myTest = new MyTest(); /** * 10个线程创建出来,每个线程执行2000次num++操作 * 我们知道,在字节码及底层,i++被抽象为三个操作 * 即先取值,再自加,再赋值操作 */ for (int i = 1; i <= 10; i++) { new Thread(() -> { for (int j = 0 ...
Java并发基础1-指令重排序与JVM内存模型
并发是Java重要的一个知识点,在编码的过程中,经常会遇见这样一种场景:单线程下的代码在多线程下出现了和预期不一样的结果,其中一个原因就是JVM对我们的代码做了指令重排序的优化。
一、指令重排序为什么需要对指令进行重排序?其目的就是对我们的代码进行运行上的优化,我们会默认期望这些语句的实际运行顺序和写的代码顺序一致。但实际上,编译器、JVM 或者 CPU 都有可能出于优化等目的,对于实际指令执行的顺序进行调整。
指令重排序是JVM为了优化指令,提高程序运行效率,在不影响单线程程序执行结果的前提下,尽可能地提高并行度。编译器、处理器也遵循这样一个目标。注意是单线程。多线程的情况下指令重排序就会给程序员带来问题。
1.1 as-if-serial指令重排序必须满足as-if-serial语义:即无论怎么样重排序,都不能够改变单线程程序运行的结果。例如:
double a = 1.0; // 1double b = 2.0; // 2double result = a * b; // 3
经过指令重排序后,可能被优化成以下:
double b = 2.0; // 2double a = 1 ...
国密算法在多语言下的适配
开源库本文中用到的加密算法实现开源项目如下:
java:https://github.com/ZZMarquis/gmhelper
golang:https://github.com/Hyperledger-TWGC/ccs-gm
js:https://github.com/JuneAndGreen/sm-crypto
SM2SM2的调试较为复杂,需要注意的点有两个:1、密钥对的生成;2、JS加解密时的特殊处理。
生成密钥对经过测试,只有golang生成的密钥对才能在golang、java和js三端通用,生成方式如下:
iniSk, _ := sm2.GenerateKey(rand.Reader)iniPk := iniSk.PublicKeypemSk, err := PrivateKeyToPEM(iniSk, nil)if err != nil { t.Errorf("private key to pem error %t", err)}fmt.Printf("pem私钥:%s", string(pemSk))p ...