Java实用工具类库中的类java.util.Random提供了产生各种类型随机数的方法,下面这篇文章主要给大家介绍了关于java.util.Random实现原理的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
概述
java.util.Random可以产生int、long、float、double以及Goussian等类型的随机数。这也是它与java.lang.Math中的方法Random()最大的不同之处,后者只产生double型的随机数。
该类的实例被用于生成伪随机数的流。该类使用一个 48 位的种子,它被一个线性同余公式所修改。如果 Random 的两个实例用同一种子创建,对每个实例完成同方法调用序列它们将生成和返回相同的数序列成同一方法调用序列,它们将生成和返回相同的数序列。
示例
public class RandomTest { public static void main(String[] args) { testRandom(); System.out.println("---------------------"); testRandom(); System.out.println("---------------------"); testRandom(); } public static void testRandom(){ Random random = new Random(1); for(int i=0; i<5; i++){ System.out.print(random.nextInt()+"\t"); } System.out.println(""); } }
输出结果:
从结果中发现,只要种子一样,获取的随机数的序列就是一致的。是一种伪随机数的实现,而不是真正的随机数。
Random 源码分析
Random 类结构
class Random implements java.io.Serializable { private final AtomicLong seed; private static final long multiplier = 0x5DEECE66DL; private static final long addend = 0xBL; private static final long mask = (1L << 48) - 1; private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
有参构造方法
public Random(long seed) { if (getClass() == Random.class) this.seed = new AtomicLong(initialScramble(seed)); else { // subclass might have overriden setSeed this.seed = new AtomicLong(); setSeed(seed); } } private static long initialScramble(long seed) { return (seed ^ multiplier) & mask; }
通过传入一个种子,来生成随机数,通过上面的例子发现,种子一样产生的随机数序列一样,如果每次使用想产生不一样的序列,那就只能每次传入一个不一样的种子。
无参构造方法
public Random() { this(seedUniquifier() ^ System.nanoTime()); } private static long seedUniquifier() { // L'Ecuyer, "Tables of Linear Congruential Generators of // Different Sizes and Good Lattice Structure", 1999 for (;;) { long current = seedUniquifier.get(); long next = current * 181783497276652981L; if (seedUniquifier.compareAndSet(current, next)) return next; } }
通过源码发现,无参的构造方法,里面帮我们自动产生了一个种子,并通过CAS自旋方式保证,每次获取的种子不一样,从而保证每次new Random()
获取的随机序列不一致。
nextInt() 方法:获取 int 随机数
public int nextInt() { return next(32); } 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)); }
从代码中我们可以发现,只要种子确定后,每次产生的数,都是采用固定的算法进行产生的,所以只要种子确定后,每次产生的序列就是固定的。
每次更新种子的时候是使用的CAS来更新的,如果高并发的环境下,性能是个问题。
安全性问题
试想下,如果这是一个摇奖平台,只要种子确定后,每次产生的序列都一样。这样就可利用这个漏洞来预测下一次开奖的号码,这样容易被一些人钻空子。
jdk建议大家尽量要使用 SecureRandom 来实现随机数的生成。
SecureRandom
SecureRandom是强随机数生成器,主要应用的场景为:用于安全目的的数据数,例如生成秘钥或者会话标示(session ID),在上文《伪随机数安全性》中,已经给大家揭露了弱随机数生成器的安全问题,而使用SecureRandom这样的强随机数生成器将会极大的降低出问题的风险。
产生高强度的随机数,有两个重要的因素:种子和算法。算法是可以有很多的,通常如何选择种子是非常关键的因素。 如Random,它的种子是System.currentTimeMillis(),所以它的随机数都是可预测的, 是弱伪随机数。
强伪随机数的生成思路:收集计算机的各种信息,键盘输入时间,内存使用状态,硬盘空闲空间,IO延时,进程数量,线程数量等信息,CPU时钟,来得到一个近似随机的种子,主要是达到不可预测性。
说的简单点就是,使用加密算法生成很长的一个随机种子,让你无法猜测出种子,也就无法推导出随机序列数。
Random性能问题
从 Random 源码中我们发现,每次获取随机数的时候都是使用CAS的方式进行更新种子的值。这样在高并发的环境中会存在大量的CAS重试,导致性能下降。这时建议大家使用ThreadLocalRandom类来实现随机数的生成。
ThreadLocalRandom 实现原理
Thread 类
Thread 类中有一个 threadLocalRandomSeed 属性。
ThreadLocalRandom 结构
SEED 变量是 threadLocalRandomSeed 在 Thread 对象中的偏移量。
ThreadLocalRandom.nextSeed() 方法
从这个方法中,我们发现,每个线程的种子值都存储在Thread对象的threadLocalRandomSeed 属性中。
结论
因为ThreadLocalRandom 中的种子存储在Thread对象中,所以高并发获取Random对象时,不会使用CAS来保证每次获取的值不一致。
每个线程维护一个它自己的种子,每个线程需要获取随机数的时候,从当前的Thread对象中获取当前线程的种子,进行获取随机数,性能大大提高。
Atas ialah kandungan terperinci 关于java.util.Random实现的方法讲解及原理介绍. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

JVM melaksanakan ciri-ciri Wora Java melalui tafsiran bytecode, API bebas platform dan pemuatan kelas dinamik: 1. Bytecode ditafsirkan sebagai kod mesin untuk memastikan operasi silang platform; 2. Perbezaan sistem operasi abstrak API standard; 3. Kelas dimuatkan secara dinamik pada masa runtime untuk memastikan konsistensi.

Versi terbaru Java berkesan menyelesaikan masalah khusus platform melalui pengoptimuman JVM, penambahbaikan perpustakaan standard dan sokongan perpustakaan pihak ketiga. 1) Pengoptimuman JVM, seperti ZGC Java11 meningkatkan prestasi pengumpulan sampah. 2) Penambahbaikan perpustakaan standard, seperti sistem modul Java9 yang mengurangkan masalah berkaitan platform. 3) Perpustakaan pihak ketiga menyediakan versi yang dioptimumkan platform, seperti OpenCV.

Proses pengesahan bytecode JVM termasuk empat langkah utama: 1) Periksa sama ada format fail kelas mematuhi spesifikasi, 2) mengesahkan kesahihan dan ketepatan arahan bytecode, 3) melakukan analisis aliran data untuk memastikan keselamatan jenis, dan 4) mengimbangi ketelitian dan prestasi pengesahan. Melalui langkah -langkah ini, JVM memastikan bahawa hanya selamat, bytecode yang betul dilaksanakan, dengan itu melindungi integriti dan keselamatan program.

Java'splatformindependenceAllowsApplicationStoranyoperatingsystemwithajvm.1) singlecodebase: writeandcompileonceforallplatforms.2) Easyupdates: UpdateTecodeForsimulteUseUlyDeployment.3)

Kemerdekaan platform Java terus dipertingkatkan melalui teknologi seperti JVM, kompilasi JIT, penyeragaman, generik, ekspresi Lambda dan Projectpanama. Sejak tahun 1990-an, Java telah berkembang dari JVM asas kepada JVM moden berprestasi tinggi, memastikan konsistensi dan kecekapan kod di platform yang berbeza.

Bagaimanakah Java mengurangkan masalah khusus platform? Java melaksanakan platform bebas melalui JVM dan perpustakaan standard. 1) Gunakan bytecode dan JVM untuk abstrak perbezaan sistem operasi; 2) Perpustakaan standard menyediakan API silang platform, seperti laluan fail pemprosesan kelas Paths, dan pengekodan aksara pemprosesan kelas charset; 3) Gunakan fail konfigurasi dan ujian pelbagai platform dalam projek sebenar untuk pengoptimuman dan debugging.

Java'splatformindependenceEnhancesMicroservicesarchitectureByOfferingDeploymentflexability, konsistensi, skalabilitas, andPortability.1) DeploymentflexabilityAllowsMicroserviceStorunonAnanyplatformWithAjvm.2) ConsistencyAcsServicSservicesSimpliesDevelanDanDevelan

GraalVM meningkatkan kemerdekaan platform Java dalam tiga cara: 1. 2. Persekitaran Runtime Bebas, menyusun program Java ke dalam fail boleh laku tempatan melalui GraalvmnativeImage; 3. Pengoptimuman Prestasi, Graal Compiler menjana kod mesin yang cekap untuk meningkatkan prestasi dan konsistensi program Java.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

mPDF
mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

Pelayar Peperiksaan Selamat
Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

Penyesuai Pelayan SAP NetWeaver untuk Eclipse
Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.

VSCode Windows 64-bit Muat Turun
Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft
