JAVA基础之放弃使用Random

news2025/1/14 18:44:44

        随机是日常生活中经常遇到的非常有趣的东西,比如说抛硬币,他的不可预知性总是让我们特别着迷,在拿不定主意时,有些人就喜欢用抛硬币的方式来帮助我们做决定。体育领域也喜欢用喜欢用抛硬币的方式来猜先。随机数功能是Java非常非常基础的功能。早在1.0的版本就引入了Random类。

Random
        Random类的使用
public static void main(String[] args) {
    Random random = new Random();
    // 0-10的随机整数
    int randomResult = random.nextInt(10);
    System.out.println(randomResult);
}
        Random的实现原理

        Random通过一个种子(seed),进行简单的计算来生成随机数的,具体算法如下:

protected int next(int bits) {
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
}

        其中multiplier,addend和mask是在类中写死的,这种算法叫线性同余算法(LCG)有兴趣的同学可以自己去了解一下,这里就不展开了。结论是算法会造成一种情况是相同的因子的相同生成次数会得到相同的数。

public static void main(String[] args) {
    Random random1 = new Random(1000L);
    Random random2 = new Random(1000L);

    for (int i = 0; i < 5; i++) {
        System.out.printf("%nrandom1的第%s次生成随机数" + random1.nextInt(100), i);
        System.out.printf("%nrandom2的第%s次生成随机数" + random2.nextInt(100), i);
    }
}

        得到结果

        由于Random使用LCG算法生成伪随机数,而且Random的随机数是可预测的会造成安全问题,所以我们需要一个安全的真随机数生成器:SecureRandom。 

SecureRandom

        内置两种随机数算法:SHA1PRNG和NativePRNG。也支持基于SPI机制对算法进行扩展。默认是NativePRNG算法。SecureRandom类会收集一些随机事件,比如鼠标点击、键盘敲击等,SecureRandom使用这些随机事件作为种子,使种子不再是可以预测的。

        ScureRandom类的使用
public static void main(String[] args) throws NoSuchAlgorithmException {
    // 使用默认算法:NativePRNG
    // SecureRandom random = new SecureRandom();
    // 指定算法:SHA1PRNG
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    int result = random.nextInt(10);
    System.out.println(result);
}

        Random的线程安全是通过AtomicLong的CAS操作保证的,java7版本发布了多线程情况下的性能优化版本的Random类:ThreadLocalRandom

ThreadLocalRandom

        ThreadLocalRandom有两项重要改动。

        第一项改动是,弃用AtomicLong,将种子seed改为普通的Long类型,避免了高竞争的情况下CAS的性能下降问题;

        第二项改动是,我们不需要再创建ThreadLocalRandom对象实例,构造函数已经设置成私有的了,可以通过ThreadLocalRandom.current()获取;

        ThreadLocalRandom类的使用
public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        int result = ThreadLocalRandom.current().nextInt(10);
        System.out.println(result);
    }
}

        在学习时,也看了其他大佬的文章,看到了他们提到的错误用法,我在这里记录一下,避免你们实践的时候会遇到。

public class RandomTest {

    private static ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Player().start();
        }
    }

    private static class Player extends Thread {
        @Override
        public void run() {
            System.out.println(getName() + ": " + RANDOM.nextInt(100));
        }
    }
}

输出结果

        这是为什么呢,实话实说我疑惑了一阵子,后来发现,所有的子线程都是在用main现场初始化的ThreadLocalRandom对象,没有经过初始化,子线程的SEED没有经过初始化就是0,大家的SEED都是相同的情况下,自然就会跟Random中落入相同的seed相同的次数获取的值都相同的陷阱中。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/858461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数字万用表测量基础知识--使用DMM测量电流

概览 DMM&#xff08;即数字万用表&#xff09;是一种电气测试和测量仪器&#xff0c;可测量直流和交流信号的电压、电流和电阻。本文介绍如何正确使用和理解数字万用表(DMM)。 使用DMM测量电流 另一个常见的测量功能是直流和交流电流测量。电压是通过与电路并联进行测量&am…

手机app测试

一、安装、卸载、更新、运行 1.安装、卸载 应用是否可以正常安装&#xff08;命令行安装&#xff1b;apk&#xff0f;ipa安装包安装&#xff09;&#xff08;有网&#xff0c;无网是否都正常&#xff09;卸载过程中出现死机&#xff0c;断电&#xff0c;重启等意外的情况&…

18 Java并发机制的底层实现原理_volatile实现原理

Java并发机制的底层实现原理_volatile实现原理 Java并发机制的底层实现原理volatile 关键字volatile的两条实现原则&#xff08;Lock前缀的作用&#xff09; Java并发机制的底层实现原理 Java代码在编译后会变成Java字节码&#xff0c;字节码被类加载器加载到JVM里&#xff0c;…

【Java并发】什么是AQS?

文章目录 什么是AQS?AQS与Synchronized的区别AQS-基本工作机制AQS是公平锁与非公平锁 什么是AQS? 全称是 AbstractQueuedSynchronizer&#xff0c;即抽象队列同步器。它是构建锁或者其他同步组件的基础框架 所谓抽象&#xff0c;其实目的就是把具体的逻辑交给子类去实现&…

springboot项目get请求下划线转驼峰@JsonProperty注解失效问题

问题&#xff1a;解决sprigboot项目get请求中有下划线的入参参数&#xff0c;如&#xff1a;first_name&#xff0c;希望在项目中将下划线格式转成firstName&#xff0c;用JsonProperty注解发现失效问题 1.核查&#xff1a;JsonProperty注解对应包是否正确 正确包&#xff1a…

2023CNSS——WEB题解(持续更新)

[Baby] SignIn 进来看到 按钮点击不了&#xff0c;想到去修改代码&#xff0c;要“检查“&#xff0c;但这里的右键和F12都不可用 还好还有其他方法 检查的各种方法 选用一种后进入检查页面 删掉这里的disabled即可 点击后得到flag [Baby] Backdoor 进入&#xff0c…

2023河南萌新联赛第(五)场 K.01BFS

文章目录 传送门题目大意题解参考代码 传送门 https://ac.nowcoder.com/acm/contest/62977/K 题目大意 给定一个 n m n \times m nm 的矩阵 G G G &#xff0c;每个点有权值 G i , j G_{i,j} Gi,j​&#xff0c;开始可以选择一个方向跳&#xff0c;每次跳跃只能跳到严格…

ECharts 折线图使用相关

一、折线图堆叠设置为不堆叠的方法 官网是这样的&#xff0c;但是不需要这种堆叠形式的如下图&#xff1a; 即&#xff1a;第2条数据值 第1条数据值 第2条数据值 第3条数据值 第2条数据值 第3条数据值 需要改成实际值展示&#xff0c;如下图&#xff1a; 只需要修改stack的…

湖南麒麟系统非正常关机导致VNC启动失败原因分析

1、故障描述 掉电后&#xff0c;启动vncserver无法启动&#xff0c;或启动后连接vncserver黑屏 2、影响范围 非正常关机流程的机器 3、故障处理过程 第一次开机后vncserver服务无法正常启动&#xff0c;使用restart手动也无法拉起。按照现场人员提醒使用reboot命令重启机器…

递归神经网络简介

一、说明 说起递归神经网络&#xff0c;递归神经网络&#xff08;RNN&#xff09;主要包括以下几种类型&#xff1a; 简单的RNN&#xff08;Simple RNN&#xff09;&#xff1a;最基本的RNN类型&#xff0c;每个时刻的输出都与前面时刻的状态有关。 循环神经网络&#xff08;R…

软件第三方CMA、CNAS测试的目的和意义,信息化建设验收测试依据是什么?

在当今互联网时代&#xff0c;软件的第三方CMA、CNAS测试成为了软件行业的重要环节。那么&#xff0c;这个测试的目的和意义是什么呢?另外&#xff0c;信息化建设验收测试依据又是什么呢?    一、软件测试第三方CMA、CNAS测试的目的和意义 1、研究进展 随着软件行业的迅…

低成本无刷高速吹风机单片机方案

高速吹风机的转速一般是普通吹风机的5倍左右。一般来说&#xff0c;吹风机的电机转速一般为2-3万转/分钟&#xff0c;而高速吹风机的电机转速一般为10万转/分钟左右。高转速增加了高风速。一般来说&#xff0c;吹风机的风力只有12-17米/秒&#xff0c;而高速吹风机的风力可以达…

信号浪涌保护器的综合应用方案

信号浪涌保护器是一种用于保护电子设备免受信号线路上的瞬态过电压和浪涌电流的影响的装置。信号浪涌保护器的原理是利用气体放电管、压敏电阻、齐纳二极管等元件&#xff0c;将信号线路上的过高电压限制在一定范围内&#xff0c;或将浪涌电流分流到地线上&#xff0c;从而减少…

gradio解决上传文件数最大为1000的限制

当使用上传文件夹功能传输超过1000个文件时&#xff0c;会报出以下错误&#xff1a; 在github上&#xff0c;最新版的gradio仓库已经解决了这一问题&#xff1a; 但是这一更改还没有正式发布&#xff0c;因此无法使用pip更新&#xff1a; 因此只能先手动git clone https://g…

webstorm debug调试vue项目

1.运行npm&#xff0c;然后控制台会打印下图中的地址&#xff0c;复制local的地址 2.run–>Edit Configuration&#xff0c;如下图 3.设置测试项 4.在你需要的js段打好断点 5.在上边框的工具栏里面有debug运行&#xff0c;点击debug运行的图标运行即可

vue新学习 05vue的创建运行原理(vue的生命周期)

01.vue的创建过程 原理解释&#xff1a; 1.定义&#xff1a; 1.Vue的生命周期是指Vue实例从创建到销毁的整个过程中经历的一系列阶段&#xff0c;Vue在关键时刻帮我们调用的一些特殊名称的函数。 2.生命周期函数的名字不可更改&#xff0c;但函数的具体内容是程序员根据需求…

星戈瑞NH2-PEG-ICG应用纳米荧光成像

欢迎来到星戈瑞荧光stargraydye! NH2-PEG-ICG是一种具有胺基的聚乙二醇修饰的吲哚菁绿染料&#xff0c;常用于纳米荧光成像应用。以下是NH2-PEG-ICG在纳米荧光成像应用中的一些特点和优势&#xff1a; **1. 荧光性能&#xff1a;**NH2-PEG-ICG在近红外光谱区域&#xff08;约7…

电商数据API接口有什么作用和意义,让我们来了解一下吧!

在现代互联网时代&#xff0c;电子商务已经成为了经济发展的重要推动力之一。越来越多的企业和个人开始通过电商平台进行商品销售&#xff0c;而准确的数据分析和及时的数据更新成为了他们的关键需求。而电商数据API接口&#xff0c;作为电商平台和第三方开发者之间的桥梁&…

星河双子塔对面万科星火城市更新规划出炉

龙岗区坂田街道欧威尔空调厂城市更新单元“工业上楼”项目规划&#xff08;草案&#xff09;已经龙岗区“工业上楼”项目工作专班2023年第四次审批会议审议通过。根据《中华人民共和国城乡规划法》《深圳经济特区城市更新条例》《深圳市城市更新办法实施细则》《深圳市“工业上…

手动创建一个DOCKER镜像

1. 我们先使用C语言写一个hello-world程序 vim hello.c # include <stdio.h>int main() {print("hello docker\n"); } 2. 将hello.c文件编译成二进制文件, 需要安装工具 yum install gcc yum install glibc-static 开始编译 gcc -static hello.c -o hello 编译…