{"id":27034,"date":"2022-01-31T15:43:46","date_gmt":"2022-01-31T14:43:46","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=27034"},"modified":"2025-06-12T08:42:55","modified_gmt":"2025-06-12T06:42:55","slug":"zufallszahl","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/zufallszahl\/","title":{"rendered":"Zufallszahlen in Java generieren"},"content":{"rendered":"\n<p>Die Generierung von Zufallszahlen (oder -Strings oder anderen zuf\u00e4lligen Objekten) ist eine der h\u00e4ufigsten Programmieraufgaben.<\/p>\n\n\n\n<p>Dieser Artikel beschreibt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>welche M\u00f6glichkeiten es in Java gibt, um Zufallszahlen zu generieren,<\/li>\n\n\n\n<li><span style=\"color: initial;\">warum es sich dabei um sogenannte \"Pseudozufallszahlen\" handelt,<\/span><\/li>\n\n\n\n<li>welche Technik hinter deren Generierung steckt,<\/li>\n\n\n\n<li>wie man Zufallszahlen in Java vorhersagen kann<\/li>\n\n\n\n<li>und wie sich die Implementierung der verschiedenen Methoden im Laufe der Java-Versionen ver\u00e4ndert hat.<\/li>\n<\/ul>\n\n\n\n<p>Erfahrene Java-Entwickler, die mit den verschiedenen M\u00f6glichkeiten zur Erstellung von Zufallswerten vertraut sind, k\u00f6nnen direkt zum Abschnitt <a href=\"#Pseudozufallszahlen_in_Java\">\"Pseudozufallszahlen in Java\"<\/a> oder <a href=\"#Anderungen_der_Implementierungen_im_Laufe_der_Zeit\">\"\u00c4nderungen der Implementierungen im Laufe der Zeit\"<\/a> springen.<\/p>\n\n\n\n<p>Die Code-Beispiele zu diesem Artikel findest du in diesem <a href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\" target=\"_blank\" rel=\"noopener\">GitHub-Repository<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-man-zufallszahlen-generiert\">Wie man Zufallszahlen generiert<\/h2>\n\n\n\n<p>Dieses Kapitel zeigt die grundlegenden Klassen und Methoden zur Generierung einer Zufallszahl in Java und was bei deren Verwendung im Hinblick auf Threadsicherheit zu beachten ist.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"java-math-random-methode\">Java Math.random() Methode<\/h3>\n\n\n\n<p>Eine der \u00e4ltesten Methoden (sie existiert seit Java 1.0), um eine zuf\u00e4llige Flie\u00dfkommazahl zu generieren, ist der Aufruf von <code>Math.random()<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">double<\/span> d = Math.random();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Der Aufruf liefert eine Zufallszahl zwischen 0 und 1. Genauer gesagt: eine <code>double<\/code>-Flie\u00dfkommazahl gr\u00f6\u00dfer oder gleich 0,0 und kleiner als 1,0.<\/p>\n\n\n\n<p><code>Math.random()<\/code> ist laut Dokumentation threadsicher. Die Synchronisation ist allerdings von Java 1.3 bis einschlie\u00dflich Java 7 fehlerhaft. Solltest du mit einer dieser Versionen arbeiten, darfst du <code>Math.random()<\/code> auf keinen Fall von verschiedenen Threads aus aufrufen.<\/p>\n\n\n\n<p>Intern ruft <code>Math.random()<\/code> die <code>nextDouble()<\/code>-Methode einer in der <code>Math<\/code>-Klasse gehaltenen statischen Instanz der im n\u00e4chsten Abschnitt besprochenen <code>Random<\/code>-Klasse auf.<\/p>\n\n\n\n<p>Weitere Details zur internen Funktionalit\u00e4t und Threadsicherheit von <code>Math.random()<\/code> findest du im <a href=\"#Implementierung_von_Mathrandom\">Kapitel \u00fcber die Implementierung dieser Methode<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"java-random-klasse\">Java Random Klasse<\/h3>\n\n\n\n<p>Ebenfalls seit Java 1.0 dabei ist die <code>java.util.Random<\/code>-Klasse. Mit dieser kannst du wie folgt eine zuf\u00e4llige <code>int<\/code>-Zahl generieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = <span class=\"hljs-keyword\">new<\/span> Random();\n<span class=\"hljs-keyword\">int<\/span> i = random.nextInt();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Der Aufruf liefert eine zuf\u00e4llige Integer-Zahl im Bereich von <code>Integer.MIN_VALUE<\/code> (= -2<sup>31<\/sup> = -2.147.483.648) bis <code>Integer.MAX_VALUE<\/code> (= 2<sup>31<\/sup>-1 = 2.147.483.647).<\/p>\n\n\n\n<p>Weitere Methoden zur Generierung von Zufallswerten sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>nextInt(int bound)<\/code> \u2013 generiert eine Zufallszahl gr\u00f6\u00dfer oder gleich 0 und kleiner als der angegebene Grenzwert <code>bound<\/code>.<\/li>\n\n\n\n<li><code>nextLong()<\/code> \u2013 generiert einen zuf\u00e4lligen <code>long<\/code>-Wert.<\/li>\n\n\n\n<li><code>nextBoolean()<\/code> \u2013 liefert einen zuf\u00e4lligen Boolean-Wert, also <code>true<\/code> oder <code>false<\/code>.<\/li>\n\n\n\n<li><code>nextFloat()<\/code> \u2013 liefert eine zuf\u00e4llig <code>float<\/code>-Zahl gr\u00f6\u00dfer oder gleich 0,0 und kleiner als 1,0.<\/li>\n\n\n\n<li><code>nextDouble()<\/code> \u2013 liefert eine zuf\u00e4llig <code>double<\/code>-Zahl gr\u00f6\u00dfer oder gleich 0,0 und kleiner als 1,0 (diese Methode wird von <code>Math.random()<\/code> aufgerufen, wie im <a href=\"#Java_Mathrandom_Methode\">vorherigen Abschnitt<\/a> beschrieben).<\/li>\n\n\n\n<li><code>nextBytes(byte[] bytes)<\/code> \u2013 f\u00fcllt das angegebene <code>byte<\/code>-Array mit zuf\u00e4lligen Bytes.<\/li>\n\n\n\n<li><code>nextGaussian()<\/code> \u2013 liefert eine normal- bzw. Gau\u00df-verteilte Zufallszahl mit einer Standardabweichung von 1.0, d. h. dass entsprechend der <a rel=\"noopener\" href=\"https:\/\/de.wikipedia.org\/wiki\/Normalverteilung\" target=\"_blank\">Normalverteilung<\/a> die Wahrscheinlichkeit einer nahe der 0 liegenden Zahl h\u00f6her ist als die Wahrscheinlichkeit einer weit von der 0 entfernten Zahl.<\/li>\n<\/ul>\n\n\n\n<p>Mit der Methode <code>setSeed(long seed)<\/code> oder dem zweiten Konstruktor <code>Random(long seed)<\/code> kannst du den sogenannten Startwert (englisch \"seed\") des Zufallszahlengenerators setzen. Das ist nur f\u00fcr besondere Anforderungen n\u00f6tig. Mehr dar\u00fcber erf\u00e4hrst du im Kapitel <a href=\"#Pseudozufallszahlen_in_Java\">Pseudozufallszahlen<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Erweiterungen von java.util.Random in Java 8<\/h4>\n\n\n\n<p>Mit der Einf\u00fchrung von Streams in Java 8 wurde <code>java.util.Random<\/code> um Methoden zur Erzeugung von Zufallszahlen-Streams erweitert. Die Methode <code>Random.ints()<\/code> generiert einen <code>IntStream<\/code>: einen Stream von zuf\u00e4lligen <code>int<\/code>-Werten.<\/p>\n\n\n\n<p>Das folgende Beispiel gibt sieben Zufallszahlen auf der Konsole aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = <span class=\"hljs-keyword\">new<\/span> Random();\nrandom.ints().limit(<span class=\"hljs-number\">7<\/span>).forEach(System.out::println);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die durch <code>limit(7)<\/code> gesetzte Limitierung auf sieben Elemente k\u00f6nnen wir auch in einer \u00fcberladenen Variante der <code>ints()<\/code>-Methode anfordern:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = <span class=\"hljs-keyword\">new<\/span> Random();\nrandom.ints(<span class=\"hljs-number\">7<\/span>).forEach(System.out::println);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Zwei weitere Varianten erlauben die Angabe von Unter- und Obergrenze der generierten Werte. Das folgende Beispiel generiert sieben Zufallszahlen gr\u00f6\u00dfer oder gleich 0 und kleiner als 1.000 \u2013 einmal durch <code>limits()<\/code> begrenzt und einmal durch den ersten Parameter der <code>ints()<\/code>-Methode.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = <span class=\"hljs-keyword\">new<\/span> Random();\nrandom.ints(<span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">1000<\/span>).limit(<span class=\"hljs-number\">7<\/span>).forEach(System.out::println);\nrandom.ints(<span class=\"hljs-number\">7<\/span>, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">1000<\/span>).forEach(System.out::println);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p> Jeweils entsprechende vier Varianten existieren f\u00fcr:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>longs()<\/code> \u2013 generiert einen <code>LongStream<\/code> von Zufallszahlen<\/li>\n\n\n\n<li><code>doubles()<\/code> \u2013 generiert einen <code>DoubleStream<\/code> von Zufallszahlen<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Threadsicherheit von java.util.Random<\/h4>\n\n\n\n<p><code>java.util.Random<\/code> ist threadsicher; du kannst also die Methoden eines einzigen <code>Random<\/code>-Objekts sicher aus mehreren Threads aufrufen.<\/p>\n\n\n\n<p>Da die erzeugten Werte keine echten Zufallszahlen sind, sondern eine Zufallszahl quasi aus der vorherigen berechnet wird (das ist stark vereinfacht ausgedr\u00fcckt; genaueres findest du im Kapitel <a href=\"#Pseudozufallszahlen_in_Java\">\"Pseudozufallszahlen\"<\/a>) \u2013 und da diese Berechnung atomar erfolgen muss, ist der Aufruf der Methode mit einem gewissen Synchronisations-Overhead verbunden.<\/p>\n\n\n\n<p>Viele gleichzeitige Aufrufe aus mehreren Threads k\u00f6nnen somit die Performance negativ beeinflussen. Im GitHub-Repo findest du das Programm <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/threads\/RandomMultipleThreadsDemo.java\" target=\"_blank\">RandomMultipleThreadsDemo<\/a>, das den Unterschied demonstriert.<\/p>\n\n\n\n<p>Die folgende Grafik zeigt, wie lange es auf meinem 6-Core-i7 dauert 100 Millionen Zufallszahlen \u00fcber ein geteiltes <code>Random<\/code>-Objekt zu erzeugen: bei einem Thread etwa eine Sekunde, bei sechs parallelen Threads \u00fcber 50 Sekunden:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"450\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-800x450.png\" alt=\"java.util.Random Multithreading Performance \u2013 geteilte Instanz\" class=\"wp-image-27354\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-800x450.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-224x126.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-336x189.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-504x284.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-672x378.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-400x225.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-600x338.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-944x531.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance-1200x675.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-single-instance-performance.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">java.util.Random Multithreading Performance \u2013 geteilte Instanz<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Gemessen habe ich hier den Extremfall, in dem die Threads ununterbrochen Zufallszahlen generieren, also st\u00e4ndig Contention verursachen (Konflikte beim Zugriff auf den gemeinsamen Status). Sollte ein Thread nur gelegentlich eine Zufallszahl generieren, tritt Contention seltener auf und ist m\u00f6glicherweise gar nicht messbar.<\/p>\n\n\n\n<p>Sofern du Thread-Contention erwartest und deine Anwendung nicht die Verwendung eines einzigen Zufallszahlengenerators erfordert (was nur in Ausnahmef\u00e4llen der Fall sein d\u00fcrfte), kannst du pro Thread ein separates <code>Random<\/code>-Objekt erzeugen \u2013 dann bleibt die Zeit f\u00fcr 100 Millionen Zufallszahlen bei etwa einer Sekunde, egal wie viele Threads parallel laufen (<a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/threads\/MultipleRandomMultipleThreadsDemo.java\" target=\"_blank\">MultipleRandomMultipleThreadsDemo<\/a> in GitHub):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"450\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-800x450.png\" alt=\"java.util.Random Multithreading Performance \u2013 eine Instanz pro Thread\" class=\"wp-image-27355\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-800x450.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-224x126.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-336x189.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-504x284.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-672x378.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-400x225.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-600x338.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-944x531.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance-1200x675.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-math-random-multiple-instances-performance.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">java.util.Random Multithreading Performance \u2013 eine Instanz pro Thread<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Besser noch ist es das im folgenden Abschnitt beschriebene <code>ThreadLocalRandom<\/code> einsetzen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"java-threadlocalrandom-klasse\">Java ThreadLocalRandom Klasse<\/h3>\n\n\n\n<p>In Java 7 wurde die Klasse <code>java.util.concurrent.ThreadLocalRandom<\/code> eingef\u00fchrt. Die statische Methode <code>ThreadLocalRandom.current()<\/code> liefert pro Thread einen von allen anderen Threads unabh\u00e4ngigen Zufallszahlengenerator. So kann es zu keiner Thread-Contention kommen, und der im vorherigen Abschnitt beschriebene Synchronisations-Overhead f\u00e4llt weg.<\/p>\n\n\n\n<p><code>ThreadLocalRandom.current()<\/code> liefert ein <code>ThreadLocalRandom<\/code>-Objekt, welches wiederum von <code>Random<\/code> erbt und damit die gleichen Methoden bereitstellt, also z. B. <code>nextInt()<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = ThreadLocalRandom.current();\n<span class=\"hljs-keyword\">int<\/span> randomNumber = random.nextInt();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Das Programm <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/threads\/ThreadLocalRandomMultipleThreadsDemo.java\" target=\"_blank\">ThreadLocalRandomMultipleThreadsDemo<\/a> misst die Performance von <code>ThreadLocalRandom<\/code>. Das Ergebnis: Die Erzeugung von 100 Millionen Zufallszahlen dauert etwa 150 ms, egal wie viele Threads gleichzeitig laufen \u2013 ein enormer Performancegewinn im Vergleich zu <code>Random<\/code> \u2013 nicht nur bei mehreren Threads, sondern auch bei nur einem:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"450\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-800x450.png\" alt=\"ThreadLocalRandom Performance\" class=\"wp-image-27356\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-800x450.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-224x126.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-336x189.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-504x284.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-672x378.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-400x225.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-600x338.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-944x531.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance-1200x675.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-performance.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">ThreadLocalRandom Performance<\/figcaption><\/figure>\n<\/div>\n\n\n<p><code>ThreadLocalRandom<\/code> sollte also immer deine erste Wahl sein.<\/p>\n\n\n\n<p>Es ist interessant, wie die Implementierung von Java 7 zu Java 8 grundlegend ver\u00e4ndert wurde. Mehr dazu im Abschnitt <a href=\"#Implementierung_von_javautilconcurrentThreadLocalRandom\">\"Implementierung von ThreadLocalRandom\"<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"erzeugen-einer-zufallszahl-aus-einem-wertebereich\">Erzeugen einer Zufallszahl aus einem Wertebereich<\/h3>\n\n\n\n<p>Eine h\u00e4ufige Anforderung ist es eine Zufallszahl aus einem bestimmten Zahlenbereich zu generieren. Ein paar M\u00f6glichkeiten hast du bereits kennengelernt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Random.nextInt(int bound)<\/code> \u2013 generiert eine zuf\u00e4llige Integer-Zahl zwischen 0 und dem angegebenen Grenzwert.<\/li>\n\n\n\n<li><code>Random.ints(int randomNumberOrigin, int randomNumberBound)<\/code> \u2013 generiert einen unendlichen Stream von Zufallszahlen im angegebenen Zahlenbereich.<\/li>\n\n\n\n<li><code>Random.ints(long streamSize, int randomNumberOrigin, int randomNumberBound)<\/code> \u2013 generiert einen Stream der angegebenen Anzahl von Zufallszahlen im angegebenen Zahlenbereich.<\/li>\n\n\n\n<li>die analogen Stream-erzeugenden Methoden <code>Random.longs()<\/code> und <code>Random.doubles()<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>(Die obere Begrenzung <code>bound<\/code> bzw. <code>randomNumberBound<\/code> ist dabei immer exklusiv, d. h. die generierten Zufallszahlen sind immer kleiner als der angegebene Maximalwert.)<\/p>\n\n\n\n<p>Wir k\u00f6nnen also<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>entweder<\/em> eine einzelne Zufallszahl zwischen 0 und einer Obergrenze erzeugen <\/li>\n\n\n\n<li><em>oder<\/em> einen Stream von Zufallszahlen, der von Unter- und Obergrenze eingeschr\u00e4nkt ist.<\/li>\n<\/ul>\n\n\n\n<p>Wollen wir jedoch eine einzelne Zufallszahl aus einem Zahlenbereich generieren, dessen Untergrenze nicht die 0 ist, k\u00f6nnen wir uns keiner vorhandenen JDK-Funktion bedienen, sondern m\u00fcssen einen Umweg gehen. Hier ein paar Beispiele:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Zufallszahl zwischen 1 und 10<\/h4>\n\n\n\n<p>Da wir nur die Obergrenze von Zufallszahlen definieren k\u00f6nnen, erstellen wir eine Zahl zwischen 0 und 9 und addieren eine 1:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = ThreadLocalRandom.current();\n<span class=\"hljs-keyword\">int<\/span> number = <span class=\"hljs-number\">1<\/span> + random.nextInt(<span class=\"hljs-number\">9<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Achtung: Obergrenzen sind immer exklusiv, d. h. der Code liefert maximal eine 9. Um die 10 einzuschlie\u00dfen, also Zahlen kleiner <em>oder gleich<\/em> 10 zu erhalten, m\u00fcssen wir den Code wie folgt abwandeln:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = ThreadLocalRandom.current();\n<span class=\"hljs-keyword\">int<\/span> number = <span class=\"hljs-number\">1<\/span> + random.nextInt(<span class=\"hljs-number\">10<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Zufallszahl zwischen 1 und 100<\/h4>\n\n\n\n<p>Um eine Zufallszahl zwischen 1 und 100 zu generieren, generieren wir eine Zahl zwischen 0 und 99 und addieren 1:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = ThreadLocalRandom.current();\n<span class=\"hljs-keyword\">int<\/span> number = <span class=\"hljs-number\">1<\/span> + random.nextInt(<span class=\"hljs-number\">99<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Analog zum vorherigen Beispiel m\u00fcssen wir <code>nextInt(100)<\/code> schreiben, wenn wir die 100 einschlie\u00dfen wollen.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Zufallszahl zwischen zwei Werten<\/h4>\n\n\n\n<p>Wenn wir h\u00e4ufiger eine Zufallszahl zwischen zwei vorgegebenen Werten ben\u00f6tigen, sollten wir die Erzeugung in eine Hilfsmethode auslagern:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> class RandomUtils\n  <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">nextInt<\/span><span class=\"hljs-params\">(Random random, <span class=\"hljs-keyword\">int<\/span> origin, <span class=\"hljs-keyword\">int<\/span> bound)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (origin &gt;= bound) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException();\n    }\n    <span class=\"hljs-keyword\">return<\/span> origin + random.nextInt(bound - origin);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Diese k\u00f6nnen wir dann bspw. wie folgt aufrufen, um eine Zufallszahl zwischen 1 und 6 inklusive zu generieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = ThreadLocalRandom.current();\n<span class=\"hljs-keyword\">int<\/span> randomNumberFrom1To6 = RandomUtils.nextInt(random, <span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">7<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>So kannst du z. B. den Wurf eines W\u00fcrfels simulieren.<\/p>\n\n\n<div class=\"convertkit-form wp-block-convertkit-form\" style=\"\"><script async data-uid=\"1427197203\" src=\"https:\/\/happycoders.kit.com\/1427197203\/index.js\" data-jetpack-boost=\"ignore\" data-no-defer=\"1\" data-no-optimize=\"1\" nowprocket><\/script><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-man-in-java-zufaellige-strings-generiert\">Wie man in Java zuf\u00e4llige Strings generiert<\/h2>\n\n\n\n<p>Wir haben bisher Methoden der <code>Random<\/code>-Klasse kennengelernt, mit denen wir zuf\u00e4llige Integer-Zahlen (<code>nextInt<\/code>), zuf\u00e4llige Double-Zahlen (<code>nextDouble<\/code>), zuf\u00e4llige Arrays (<code>nextBytes<\/code>) und zuf\u00e4llige Boolean-Werte (<code>nextBoolean<\/code>) erstellen k\u00f6nnen.<\/p>\n\n\n\n<p>Manchmal ben\u00f6tigen wir jedoch einen zuf\u00e4lligen String \u2013 also einen String, der mit einer zuf\u00e4lligen oder vorgegebenen Anzahl zuf\u00e4lliger Zeichen gef\u00fcllt ist.<\/p>\n\n\n\n<p>Wir k\u00f6nnen dazu einen <code>StringBuilder<\/code> nach und nach mit zuf\u00e4lligen Kleinbuchstaben f\u00fcllen (diese und die folgenden Methoden findest du in der <a href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/util\/RandomUtils.java\" target=\"_blank\" rel=\"noopener\">RandomUtils-Klasse in GitHub<\/a>):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> String <span class=\"hljs-title\">randomLowerCaseString<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> length)<\/span> <\/span>{\n  StringBuilder sb = <span class=\"hljs-keyword\">new<\/span> StringBuilder();\n  Random r = ThreadLocalRandom.current();\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; length; i++) {\n    <span class=\"hljs-keyword\">char<\/span> c = (<span class=\"hljs-keyword\">char<\/span>) (<span class=\"hljs-string\">'a'<\/span> + r.nextInt(<span class=\"hljs-number\">26<\/span>));\n    sb.append(c);\n  }\n  <span class=\"hljs-keyword\">return<\/span> sb.toString();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Etwas komplizierter wird es, wenn wir den Zeichenbereich erweitern wollen, z. B. auf Gro\u00dfbuchstaben, Ziffern und das Leerzeichen. Dann m\u00fcssen wir ein Alphabet festlegen und daraus ein zuf\u00e4lliges Zeichen entnehmen: <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> String ALPHANUMERIC_WITH_SPACE_ALPHABET =\n    <span class=\"hljs-string\">\" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> String <span class=\"hljs-title\">randomAlphanumericalWithSpaceString<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> length)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> randomString(length, ALPHANUMERIC_WITH_SPACE_ALPHABET);\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> String <span class=\"hljs-title\">randomString<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> length, String alphabet)<\/span> <\/span>{\n  StringBuilder sb = <span class=\"hljs-keyword\">new<\/span> StringBuilder();\n  Random r = ThreadLocalRandom.current();\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; length; i++) {\n    <span class=\"hljs-keyword\">int<\/span> pos = r.nextInt(alphabet.length());\n    <span class=\"hljs-keyword\">char<\/span> c = alphabet.charAt(pos);\n    sb.append(c);\n  }\n  <span class=\"hljs-keyword\">return<\/span> sb.toString();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Seit Java 8 k\u00f6nnen wir die <code>randomString()<\/code>-Methode auch mit einem Stream implementieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> String <span class=\"hljs-title\">randomStringWithStream<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> length, String alphabet)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> ThreadLocalRandom.current()\n      .ints(length, <span class=\"hljs-number\">0<\/span>, alphabet.length())\n      .map(alphabet::charAt)\n      .collect(StringBuilder::<span class=\"hljs-keyword\">new<\/span>, StringBuilder::appendCodePoint, StringBuilder::append)\n      .toString();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Alternativ kannst du auch eine der zahlreichen Methoden der Klasse <a rel=\"noopener\" href=\"https:\/\/commons.apache.org\/proper\/commons-lang\/apidocs\/org\/apache\/commons\/lang3\/RandomStringUtils.html\" target=\"_blank\">RandomStringUtils<\/a> aus dem Open Source Projekt <a href=\"https:\/\/commons.apache.org\/proper\/commons-lang\/\" target=\"_blank\" rel=\"noopener\">Apache Commons Lang<\/a> einsetzen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"pseudozufallszahlen-in-java\">Pseudozufallszahlen in Java <\/h2>\n\n\n\n<p>Dieser Artikel hat bereits einige Male das Thema \"Pseudozufallszahlen\" erw\u00e4hnt. Jetzt ist es an der Zeit das Thema genauer unter die Lupe zu nehmen.<\/p>\n\n\n\n<p>Wie bereits kurz angesprochen, erzeugt <code>Random<\/code> keine <em>echten<\/em> Zufallszahlen. Das kann es gar nicht, denn Computer basieren auf Algorithmen, und Algorithmen sind konkrete Vorschriften, die von einer bestimmten Eingabe zu einer bestimmten Ausgabe f\u00fchren.<\/p>\n\n\n\n<p>Was stattdessen generiert wird, sind sogenannte \"Pseudozufallszahlen\". Diese basieren auf einer Folge von Zahlen, die bei einem Startwert beginnt (dem sogenannten \"seed\") und bei der die n\u00e4chste Zahl jeweils aus der vorherigen berechnet wird.<\/p>\n\n\n\n<p>Die Berechnungsvorschrift ist so konstruiert, dass die generierten Zahlen a) den Eindruck erwecken zuf\u00e4llig zu sein und b) gleichm\u00e4\u00dfig im Zahlenraum verteilt sind (die mathematische Theorie dahinter kannst du im <a rel=\"noopener\" href=\"https:\/\/de.wikipedia.org\/wiki\/Kongruenzgenerator\" target=\"_blank\">Wikipedia-Artikel \"Kongruenzgenerator\"<\/a> nachlesen).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"startwert-seed\">Startwert \"seed\"<\/h3>\n\n\n\n<p>Der Startwert \"seed\" wird beim Aufruf des <code>Random()<\/code>-Konstruktors aus der Systemzeit generiert. Dadurch ist die Wahrscheinlichkeit hoch, dass bei jeder Erzeugung eines <code>Random<\/code>-Objekts die Zufallszahlen-Sequenz an einer anderen Position beginnt.<\/p>\n\n\n\n<p>Wir k\u00f6nnen den <code>seed<\/code>-Wert aber auch selbst festlegen: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>im Konstruktor <code>Random(long seed)<\/code> <\/li>\n\n\n\n<li>oder mit der Methode <code>setSeed(long seed)<\/code><\/li>\n<\/ul>\n\n\n\n<p>Wenn wir das tun, erhalten wir immer die gleiche Folge von Zufallszahlen. Das k\u00f6nnen wir ganz einfach \u00fcberpr\u00fcfen: Der folgende Code (Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/seed\/SetSeedExample.java\" target=\"_blank\" rel=\"noopener\">SetSeedExample in GitHub<\/a>) gibt bei jedem Start \u2013 auf jedem Betriebssystem und mit jeder Java-Version \u2013 zweimal die Zahlenfolge 30, 63, 48, 84, 70 aus.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Random random = <span class=\"hljs-keyword\">new<\/span> Random(<span class=\"hljs-number\">42<\/span>);\n<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">5<\/span>; i++) {\n  System.out.println(random.nextInt(<span class=\"hljs-number\">100<\/span>));\n}\n\nrandom.setSeed(<span class=\"hljs-number\">42<\/span>);\n<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">5<\/span>; i++) {\n  System.out.println(random.nextInt(<span class=\"hljs-number\">100<\/span>));\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Warum beginnt die Zahlenfolge nicht bei 42?<\/p>\n\n\n\n<p>Die Antwort findest du im n\u00e4chsten Abschnitt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"ableitung-von-zufallszahlen-aus-dem-zustand-des-zufallszahlengenerators\">Ableitung von Zufallszahlen aus dem Zustand des Zufallszahlengenerators<\/h3>\n\n\n\n<p>Mit dem \"seed\"-Wert bestimmen wir nicht die erste Zufallszahl, sondern den Startzustand des Zufallszahlengenerators. In der <code>Random<\/code>-Klasse wird der Status in einer 48-Bit-Zahl gespeichert, die aus dem \"seed\" berechnet wird.<\/p>\n\n\n\n<p>Unpassenderweise wird der Zustand in einer Variablen gespeichert, die ebenfalls den Namen <code>seed<\/code> tr\u00e4gt; passender w\u00e4re der Name <code>state<\/code> gewesen. Der jeweilige Folgestatus wird \u00fcber folgende Formel berechnet:<\/p>\n\n\n\n<p class=\"has-text-align-center\">seed = (seed * 25.214.903.917 + 11) &amp; 2<sup>48<\/sup>-1<\/p>\n\n\n\n<p>Aus diesem 48-Bit-Wert werden dann linksb\u00fcndig so viele Bits entnommen, wie f\u00fcr den angeforderte Zufallswert ben\u00f6tigt werden, z. B. 32 Bit f\u00fcr ein <code>int<\/code>:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"115\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-800x115.png\" alt=\"Ableitung einer 32-Bit-Zufallszahl aus dem Random-48-Bit-Status\" class=\"wp-image-27327\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-800x115.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-224x32.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-336x48.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-504x72.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-672x97.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-400x58.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-600x86.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-944x136.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-1200x173.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Ableitung einer 32-Bit-Zufallszahl aus dem Random-48-Bit-Status<\/figcaption><\/figure>\n<\/div>\n\n\n<p>... oder 1 Bit f\u00fcr ein <code>boolean<\/code>:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"116\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-800x116.png\" alt=\"Ableitung einer 1-Bit-Zufallszahl aus dem Random-48-Bit-Status\" class=\"wp-image-27328\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-800x116.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-224x32.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-336x49.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-504x73.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-672x97.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-400x58.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-600x87.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-944x136.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-1200x173.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Ableitung einer 1-Bit-Zufallszahl aus dem Random-48-Bit-Status<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Und f\u00fcr Zahlen, die mehr als 48 Bit ben\u00f6tigen, wie <code>long<\/code> oder <code>double<\/code>? <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>F\u00fcr ein <code>long<\/code> werden 32 Bit entnommen, dann wird der Folgezustand berechnet, dann weitere 32 Bit entnommen.<\/li>\n\n\n\n<li>F\u00fcr ein double werden einmal 26 Bit und noch einmal 27 Bit entnommen, ergibt 53 Bit (was der Genauigkeit eines <code>double<\/code>-Werts entspricht).<\/li>\n<\/ul>\n\n\n\n<p>Aus den 48 Bit werden nie mehr als 32 Bit entnommen. Warum ist der Status dann 48 Bit lang und nicht 32?<\/p>\n\n\n\n<p>Der Grund ist der folgende:<\/p>\n\n\n\n<p>Wenn der Status nur 32 Bit lang w\u00e4re, w\u00fcrde einer bestimmten Integer-Zufallszahl immer die gleiche Zufallszahl folgen. Das bedeutet wiederum, dass eine einzelne Zufallszahl gen\u00fcgen w\u00fcrde, um alle zuk\u00fcnftigen Zufallszahlen vorherzusagen.<\/p>\n\n\n\n<p>Dadurch, dass uns bei einem 48-Bit-Status die restlichen 16 Bit verborgen bleiben, gibt es f\u00fcr einen 32-Bit-Wert 2<sup>16<\/sup>, also 65.536 verschiedene Status, in denen sich der Zufallszahlengenerator aktuell befinden k\u00f6nnte. Ein- und dieselbe Integer-Zufallszahl kann also 65.536 verschiedene Nachfolger haben. Das macht eine Vorhersage aus einer einzelnen Zahl unm\u00f6glich. <\/p>\n\n\n\n<p>Wenn wir allerdings zwei aufeinanderfolgende Zufallszahlen kennen, sieht das ganz anders aus. Mehr dazu im Abschnitt <a href=\"#Vorhersagbarkeit_von_Zufallszahlen\">\"Vorhersagbarkeit von Zufallszahlen\"<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"generierung-von-pseudozufallszahlen-in-java-util-random\">Generierung von Pseudozufallszahlen in java.util.Random<\/h3>\n\n\n\n<p>Wie sieht das ganze im Quellcode von <code>java.util.Random<\/code> aus?<\/p>\n\n\n\n<p>Beginnen wir mit der <code>nextInt()<\/code>-Methode:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">nextInt<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> next(<span class=\"hljs-number\">32<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die aufgerufene <code>next()<\/code>-Methode sieht wie folgt aus.<\/p>\n\n\n\n<p>(Ich habe die urspr\u00fcngliche Implementierung bis Java 1.3 abgedruckt, da diese am einfachsten zu verstehen ist. Die aktuelle \u2013 optimierte, aber funktionell gleiche \u2013 Implementierung findest du weiter unten im Kapitel <a href=\"#Anderungen_der_Implementierungen_im_Laufe_der_Zeit\">\"\u00c4nderungen der Implementierungen im Laufe der Zeit\"<\/a>.)<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> multiplier = <span class=\"hljs-number\">0x5DEECE66DL<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> addend = <span class=\"hljs-number\">0xBL<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> mask = (<span class=\"hljs-number\">1L<\/span> &lt;&lt; <span class=\"hljs-number\">48<\/span>) - <span class=\"hljs-number\">1<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\">\/\/ ...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-keyword\">synchronized<\/span> <span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">next<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> bits)<\/span> <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">long<\/span> nextseed = (seed * multiplier + addend) &amp; mask;\n<\/span><\/span><span class='shcb-loc'><span>    seed = nextseed;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-keyword\">int<\/span>)(nextseed &gt;&gt;&gt; (<span class=\"hljs-number\">48<\/span> - bits));\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Zeile 8 implementiert die im vorangegangenen Abschnitt vorgestellte Formel zur Berechnung des Folgezustands.<\/p>\n\n\n\n<p>In Zeile 10 werden die angeforderten Bits durch \"right shift\" und Casting auf <code>int<\/code> extrahiert. Die folgende Grafik zeigt das f\u00fcr 32 Bit:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"157\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-800x157.png\" alt=\"Random.next(32): Rechts-Shift um 16 Bit und Cast auf int\" class=\"wp-image-27334\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-800x157.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-224x44.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-336x66.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-504x99.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-672x132.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-400x79.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-600x118.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-944x185.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift-1200x236.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-32-bit-right-shift.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Random.next(32): Rechts-Shift um 16 Bit und Cast auf int<\/figcaption><\/figure>\n<\/div>\n\n\n<p>... und einmal f\u00fcr 1 Bit:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"157\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-800x157.png\" alt=\"Random.next(1): Rechts-Shift um 47 Bit und Cast auf int\" class=\"wp-image-27335\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-800x157.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-224x44.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-336x66.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-504x99.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-672x132.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-400x79.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-600x118.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-944x185.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift-1200x236.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-ranom-1-bit-right-shift.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Random.next(1): Rechts-Shift um 47 Bit und Cast auf int<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Die <code>nextBoolean()<\/code>-Methode muss dann nur noch pr\u00fcfen, ob die so erhaltene 1-Bit-Zahl 1 oder 0 ist:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">nextBoolean<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> next(<span class=\"hljs-number\">1<\/span>) != <span class=\"hljs-number\">0<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>nextLong()<\/code>-Methode holt sich, wie oben erw\u00e4hnt, zun\u00e4chst 32 Bit, schiebt diese um 32 Bit nach links und addiert eine zweite 32-Bit-Zahl:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">nextLong<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> ((<span class=\"hljs-keyword\">long<\/span>)(next(<span class=\"hljs-number\">32<\/span>)) &lt;&lt; <span class=\"hljs-number\">32<\/span>) + next(<span class=\"hljs-number\">32<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>nextDouble()<\/code>-Methode ist etwas komplizierter (auch hier zun\u00e4chst die \u2013 etwas leichter zu lesende, da noch nicht hochoptimierte \u2013 urspr\u00fcngliche Implementierung bis Java 7):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">nextDouble<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">long<\/span> l = ((<span class=\"hljs-keyword\">long<\/span>)(next(<span class=\"hljs-number\">26<\/span>)) &lt;&lt; <span class=\"hljs-number\">27<\/span>) + next(<span class=\"hljs-number\">27<\/span>);\n    <span class=\"hljs-keyword\">return<\/span> l \/ (<span class=\"hljs-keyword\">double<\/span>)(<span class=\"hljs-number\">1L<\/span> &lt;&lt; <span class=\"hljs-number\">53<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die Methode f\u00fchrt folgende zwei Schritte aus:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Verkettung einer 26-Bit Zufallszahl mit einer 27-Bit Zufallszahl zu einer 53-Bit-Zahl (also eine Zahl zwischen 0 und 2<sup>53<\/sup>-1)<\/li>\n\n\n\n<li>Teilung durch 2<sup>53<\/sup> (eins mehr als die h\u00f6chste Zahl, die in Schritt 1 generiert werden k\u00f6nnte)<\/li>\n<\/ol>\n\n\n\n<p>Das ergibt dann eine Zahl &gt;= 0,0 und &lt; 1,0.<\/p>\n\n\n\n<p>Warum werden f\u00fcr ein <code>double<\/code> nur 53 Bit verwendet und nicht 64? Der Grund ist, dass in Flie\u00dfkommazahlen mit doppelter Genauigkeit 53 Bit f\u00fcr Vorzeichen und Mantisse verwendet werden und 11 Bit f\u00fcr den Exponenten. Eine detailliertere Erkl\u00e4rung findest du im <a href=\"https:\/\/de.wikipedia.org\/wiki\/Doppelte_Genauigkeit\" target=\"_blank\" rel=\"noopener\">Wikipedia-Artikel \"Doppelte Genauigkeit\"<\/a>.<\/p>\n\n\n\n<p>Analog verwendet die <code>nextFloat()<\/code>-Methode 24 Bit und nicht 32 (s. <a href=\"https:\/\/de.wikipedia.org\/wiki\/Einfache_Genauigkeit\" target=\"_blank\" rel=\"noopener\">Wikipedia-Artikel \"Einfache Genauigkeit\"<\/a>):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">float<\/span> <span class=\"hljs-title\">nextFloat<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> next(<span class=\"hljs-number\">24<\/span>) \/ ((<span class=\"hljs-keyword\">float<\/span>)(<span class=\"hljs-number\">1<\/span> &lt;&lt; <span class=\"hljs-number\">24<\/span>));\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"vorhersagbarkeit-von-zufallszahlen\">Vorhersagbarkeit von Zufallszahlen<\/h3>\n\n\n\n<p>Im vorletzten Abschnitt habe ich die Behauptung aufgestellt, dass wir aus zwei aufeinanderfolgenden Pseudozufallszahlen vorhersagen k\u00f6nnen, welche weiteren Zahlen folgen. Diese Behauptung l\u00e4sst sich mit einem einfachen Test \u00fcberpr\u00fcfen.<\/p>\n\n\n\n<p>Das Programm <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/sequence\/RandomIntegerPairRepetitionFinder.java\" target=\"_blank\">RandomIntegerPairRepetitionFinder<\/a> generiert f\u00fcr alle 2<sup>32<\/sup> Integer-Zahlen jeweils alle 2<sup>16<\/sup> m\u00f6glichen Seed-Werte \u2013 und daraus die 2<sup>16<\/sup> m\u00f6glichen Nachfolger. Findet das Programm ein- und dasselbe Paar von aufeinanderfolgenden Pseudozufallszahlen mehr als einmal, gibt es dieses auf der Konsole aus. <\/p>\n\n\n\n<p>Nach 24 Stunden wurde auf meinem Laptop keine Wiederholung gefunden. Das Programm m\u00fcsste allerdings insgesamt knapp 1.200 Stunden, also 50 Tage, laufen, um alle Kombinationen zu \u00fcberpr\u00fcfen. So viel Zeit habe ich nicht, daher kann ich meine Behauptung nicht beweisen.<\/p>\n\n\n\n<p>Trotzdem k\u00f6nnen wir ein Programm schreiben, dass aus zwei gegebenen Zufallszahlen alle weiteren vorhersagt. Solch ein Programm kann erkennen, ob f\u00fcr die Eingabe nur eine m\u00f6gliche Sequenz existiert \u2013 und um eine dritte Zahl bitten, sollten zwei nicht ausreichen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-man-die-naechste-zufallszahl-in-java-vorhersagt\">Wie man die n\u00e4chste Zufallszahl in Java vorhersagt<\/h3>\n\n\n\n<p>Wenn zwei durch <code>Random.nextInt()<\/code> erzeugte Zufallszahlen gegeben sind, lassen sich relativ leicht die weiteren Zufallszahlen vorhersagen. <\/p>\n\n\n\n<p>Dazu bestimmen wir f\u00fcr die erste gegebene Zahl die 2<sup>16<\/sup> m\u00f6glichen Seed-Werte, generieren daraus die jeweilige Folgezahl und pr\u00fcfen, ob diese mit der zweiten gegebenen Zahl \u00fcbereinstimmt. Ist das der Fall, k\u00f6nnen wir ausgehend vom so ermittelten Seed-Wert alle weiteren Zufallszahlen berechen.<\/p>\n\n\n\n<p>Den vollst\u00e4ndigen Code dazu findest du in der Klasse <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/predictor\/RandomIntegerPredictor.java\" target=\"_blank\">RandomIntegerPredictor<\/a>.<\/p>\n\n\n\n<p>Der folgende Code zeigt die Methode, die den Seed-Wert bestimmt. Ich habe sie f\u00fcr den Abdruck in diesem Artikel dahingehend vereinfacht, dass sie nur zwei Eingabezahlen verwendet. Der Code in der verlinkten Klasse kann auch eine l\u00e4ngere Eingabefolge verarbeiten.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">int<\/span> NUMBER_OF_POSSIBLE_SEEDS = <span class=\"hljs-number\">1<\/span> &lt;&lt; <span class=\"hljs-number\">16<\/span>;\n\n<span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> multiplier = <span class=\"hljs-number\">0x5DEECE66DL<\/span>;\n<span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> addend = <span class=\"hljs-number\">0xBL<\/span>;\n<span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> mask = (<span class=\"hljs-number\">1L<\/span> &lt;&lt; <span class=\"hljs-number\">48<\/span>) - <span class=\"hljs-number\">1<\/span>;\n\n<span class=\"hljs-comment\">\/\/ ...<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">getSeedMatchingForSequence<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-keyword\">long<\/span> firstNumberSeedBase = Integer.toUnsignedLong(givenNumbers&#091;<span class=\"hljs-number\">0<\/span>]) &lt;&lt; <span class=\"hljs-number\">16<\/span>;\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> noise = <span class=\"hljs-number\">0<\/span>; noise &lt; NUMBER_OF_POSSIBLE_SEEDS; noise++) {\n    <span class=\"hljs-keyword\">long<\/span> seed = firstNumberSeedBase | noise;\n    <span class=\"hljs-keyword\">long<\/span> nextSeed = getNextSeed(seed);\n    <span class=\"hljs-keyword\">int<\/span> nextInt = (<span class=\"hljs-keyword\">int<\/span>) (nextSeed &gt;&gt;&gt; <span class=\"hljs-number\">16<\/span>);\n    <span class=\"hljs-keyword\">if<\/span> (nextInt == givenNumbers&#091;<span class=\"hljs-number\">1<\/span>]) {\n      <span class=\"hljs-keyword\">return<\/span> seed;\n    }\n  }\n\n  <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(\n      <span class=\"hljs-string\">\"Found no matching seed; please verify your input sequence.\"<\/span>);\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">getNextSeed<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">long<\/span> seed)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (seed * multiplier + addend) &amp; mask;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Aus dem so erhaltenen Seed-Wert k\u00f6nnen wir die weitere Zahlenfolge ableiten:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] predict(<span class=\"hljs-keyword\">int<\/span> numberOfPredictions) {\n  <span class=\"hljs-keyword\">long<\/span> seed = getSeedMatchingForSequence();\n\n  <span class=\"hljs-comment\">\/\/ Skip the given numbers<\/span>\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; givenNumbers.length; i++) {\n    seed = getNextSeed(seed);\n  }\n\n  <span class=\"hljs-comment\">\/\/ Get the predictions<\/span>\n  <span class=\"hljs-keyword\">int<\/span>&#091;] predictions = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;numberOfPredictions];\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; numberOfPredictions; i++) {\n    predictions&#091;i] = (<span class=\"hljs-keyword\">int<\/span>) (seed &gt;&gt;&gt; <span class=\"hljs-number\">16<\/span>);\n    seed = getNextSeed(seed);\n  }\n\n  <span class=\"hljs-keyword\">return<\/span> predictions;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Im GitHub-Repo befindet sich eine Demo, <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/predictor\/RandomIntegerPredictorDemo.java\" target=\"_blank\">RandomIntegerPredictorDemo<\/a>, die zwei Zufallszahlen ausgibt, dann die n\u00e4chsten 10 Zufallszahlen vorhersagen l\u00e4sst und schlie\u00dflich 10 weitere Zufallszahlen ausgibt. Die Vorhersage stimmt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Two random numbers:\n-1,179,305,299\n435,136,901\n\nPredicting 10 random numbers:\n-2,139,482,012\n1,388,148,251\n1,134,856,645\n-1,205,820,716\n182,240,689\n...\n\nNext *actual* random numbers:\n-2,139,482,012\n1,388,148,251\n1,134,856,645\n-1,205,820,716\n182,240,689\n...<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Im Repo befindet sich au\u00dferdem der Kommandozeilen-Runner <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/java-random-demo\/blob\/main\/src\/main\/java\/eu\/happycoders\/random\/predictor\/RandomIntegerPredictorRunner.java\" target=\"_blank\">RandomIntegerPredictorRunner<\/a>, den du (nachdem du den Code compiliert hast) wie folgt aufrufen kannst:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">$ java eu.happycoders.random.predictor.RandomIntegerPredictorRunner 5 999571443 25208007\nGiven numbers: &#091;999571443, 25208007]\nPredicting 5 random numbers...\n-1,315,941,039\n136,476,741\n1,077,533,899\n-211,240,302\n143,354,061\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Der ersten Parameter, 5, gibt an, wie viele Folgezahlen angezeigt werden sollen; die folgenden Parameter sind die bekannte Zufallszahlenfolge. Ausgegeben wird die Vorhersage der folgenden Zufallszahlen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"java-securerandom-klasse\">Java SecureRandom Klasse<\/h2>\n\n\n\n<p>Im letzten Abschnitt des vorherigen Kapitels hast du gesehen, wie man aus nur zwei auseinanderfolgenden Zufallszahlen alle weiteren vorhersagen kann. <\/p>\n\n\n\n<p>F\u00fcr gewisse Anforderungen (z. B. Kryptographie) ist diese Vorhersagberkeit nicht akzeptabel. In solchen F\u00e4llen ben\u00f6tigen wir einen \"sicheren\" Zufallszahlengenerator.<\/p>\n\n\n\n<p>Bereits seit Java 1.1 gibt es die Klasse <code>java.security.SecureRandom<\/code>. Diese generiert \"kryptographisch starke\" Zufallszahlen, wie sie in <a rel=\"noopener\" href=\"https:\/\/www.ietf.org\/rfc\/rfc1750.txt\" target=\"_blank\">RFC 1750 \"Randomness Recommendations for Security\"<\/a> definiert sind.<\/p>\n\n\n\n<p>\"Kryptografisch stark\" kann auf eine der folgenden zwei Arten (oder eine Kombination aus beiden) implementiert werden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Eine deterministische Folge wie bei <code>Random<\/code>, allerdings mit wesentich gr\u00f6\u00dferem \"Noise\" (die Bits des Seeds, die nicht in die generierte Zufallszahl eingehen), so dass ein Reverse Engineering des Seeds aus einer gegebenen Sequenz mit heutiger Hardware praktisch unm\u00f6glich wird.<\/li>\n\n\n\n<li>Echte Zufallszahlen, generiert durch <a rel=\"noopener\" href=\"https:\/\/de.wikipedia.org\/wiki\/Zufallszahlengenerator#Physikalischer_Zufallszahlengenerator\" target=\"_blank\">spezielle Hardware<\/a>, die z. B. radioaktive Zerfallsvorg\u00e4nge misst.<\/li>\n<\/ul>\n\n\n\n<p>Verschiedene Arten von sicheren Zufallszahlengeneratoren k\u00f6nnen \u00fcber das Java Service Provider Interface (SPI) zur Verf\u00fcgung gestellt und zur Laufzeit \u00fcber <code>SecureRandom.getInstance(String algorithm)<\/code> und einige \u00fcberladene Varianten dieser Methode ausgew\u00e4hlt werden.<\/p>\n\n\n\n<p>Der Konstruktor von <code>SecureRandom<\/code> liefert eine Standard-Implementierung. <code>SecureRandom<\/code> erbt von <code>Random<\/code> und stellt somit die gleichen Methoden zur Verf\u00fcgung. Das folgende Beispiel zeigt, wie du eine stark zuf\u00e4llige Flie\u00dfkommazahl generieren kannst:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">SecureRandom secureRandom = <span class=\"hljs-keyword\">new<\/span> SecureRandom();\n<span class=\"hljs-keyword\">double<\/span> strongRandomNumber = secureRandom.nextDouble();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Weitere Details findest du im <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/api\/java.base\/java\/security\/SecureRandom.html\" target=\"_blank\"><code>SecureRandom<\/code>-JavaDoc<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"aenderungen-der-implementierungen-im-laufe-der-zeit\">\u00c4nderungen der Implementierungen im Laufe der Zeit<\/h2>\n\n\n\n<p>In diesem Abschnitt erf\u00e4hrst du, wie die in diesem Artikel vorgestellten Methoden zur Generierung von Zufallszahlen implementiert sind und wie (und warum) die Implementierungen im Laufe der Java-Versionen \u00fcberarbeitet wurden.  <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"implementierung-von-math-random\">Implementierung von Math.random()<\/h3>\n\n\n\n<p>Die statische Methode <code>Math.random()<\/code> ruft intern auf einer statischen Instanz der <code>Random<\/code>-Klasse die <code>nextDouble()<\/code>-Methode auf. Der Code f\u00fcr die Erzeugung des statischen <code>Random<\/code>-Objekts wurde mehrmals ge\u00e4ndert.<\/p>\n\n\n\n<p>In Java 1.0 wurde die <code>Math.random()<\/code>-Methode einfach mit dem <code>synchronized<\/code>-Keyword versehen. Dies war korrekt, f\u00fchrte aber zu einem hohen Synchronisation-Overhead:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">synchronized<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">random<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (randomNumberGenerator == <span class=\"hljs-keyword\">null<\/span>)\n        randomNumberGenerator = <span class=\"hljs-keyword\">new<\/span> Random();\n    <span class=\"hljs-keyword\">return<\/span> randomNumberGenerator.nextDouble();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In Java 1.3 wurde auf das <a href=\"https:\/\/www.happycoders.eu\/de\/java\/double-checked-locking\/\">\"Double-Checked Locking\"-Pattern<\/a> umgestellt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ !!! DON'T DO THIS - NOT THREAD-SAFE !!!<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">random<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (randomNumberGenerator == <span class=\"hljs-keyword\">null<\/span>) initRNG();\n    <span class=\"hljs-keyword\">return<\/span> randomNumberGenerator.nextDouble();\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">synchronized<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">initRNG<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (randomNumberGenerator == <span class=\"hljs-keyword\">null<\/span>) \n        randomNumberGenerator = <span class=\"hljs-keyword\">new<\/span> Random();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Diese vermeintlich performantere Implementierung ist nicht threadsicher! Aufgrund des unsynchronisierten lesenden Zugriffs auf <code>randomNumberGenerator<\/code> in der <code>random()<\/code>-Methode k\u00f6nnte ein Thread an dieser Stelle ein unvollst\u00e4ndig initialisiertes Objekt sehen. Eine ausf\u00fchrliche Erkl\u00e4rung findest du im zuvor verlinkten Artikel.<\/p>\n\n\n\n<p>Erst in Java 8 wurde dieser Fehler erkannt und auf das <a href=\"https:\/\/www.happycoders.eu\/de\/java\/initialization-on-demand-holder-idiom\/\">\"Initialization on Demand Holder\"-Pattern<\/a> umgestellt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RandomNumberGeneratorHolder<\/span> <\/span>{\n    <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Random randomNumberGenerator = <span class=\"hljs-keyword\">new<\/span> Random();\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">random<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Bei diesem Pattern wird <code>randomNumberGenerator<\/code> erst dann erzeugt, wenn es ben\u00f6tigt wird; gleichzeitig garantiert die JVM die korrekte Synchronisierung beim Initialisieren der <code>RandomNumberGeneratorHolder<\/code>-Klasse.<\/p>\n\n\n\n<p>An dieser Implementierung hat sich bis Java 18 nichts weiter ge\u00e4ndert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"implementierung-von-java-util-random\">Implementierung von java.util.Random<\/h3>\n\n\n\n<p>Im Kapitel <a href=\"#Pseudozufallszahlen_in_Java\">\"Pseudozufallszahlen in Java\"<\/a> habe ich die grunds\u00e4tzliche Implementierung der <code>Random<\/code>-Klasse anhand deren Java-1.0-Quellcode erkl\u00e4rt. Die \u00f6ffentlichen Methoden rufen intern die Methode <code>next(int bits)<\/code> auf.<\/p>\n\n\n\n<p>Deren Synchronisation erfolgte urspr\u00fcnglich \u00fcber das <code>synchronized<\/code>-Keyword, das zwar einfach einzusetzen ist, aber \u2013 insbesondere bis einschlie\u00dflich Java 5 \u2013 einen hohen Performance-Overhead verursachte.<\/p>\n\n\n\n<p>Hier noch einmal der Code aus Java 1.0:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-31\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">long<\/span> seed;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">synchronized<\/span> <span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">next<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> bits)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">long<\/span> nextseed = (seed * multiplier + addend) &amp; mask;\n    seed = nextseed;\n    <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-keyword\">int<\/span>)(nextseed &gt;&gt;&gt; (<span class=\"hljs-number\">48<\/span> - bits));\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-31\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In Java 1.4 wurde der Seed-Wert in einem (damals noch internen) <code>sun.misc.AtomicLong<\/code> gespeichert und mit <code>attemptUpdate()<\/code> ge\u00e4ndert. Diese Methode arbeitet mit <a rel=\"noopener\" href=\"https:\/\/de.wikipedia.org\/wiki\/Compare-and-swap\" target=\"_blank\">Compare-and-set<\/a>, also optimistischem Locking:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-32\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">import<\/span> sun.misc.AtomicLong;\n\n<span class=\"hljs-keyword\">private<\/span> AtomicLong seed;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">next<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> bits)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">long<\/span> oldseed, nextseed;\n    <span class=\"hljs-keyword\">do<\/span> {\n      oldseed = seed.get();\n      nextseed = (oldseed * multiplier + addend) &amp; mask;\n    } <span class=\"hljs-keyword\">while<\/span> (!seed.attemptUpdate(oldseed, nextseed));\n    <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-keyword\">int<\/span>)(nextseed &gt;&gt;&gt; (<span class=\"hljs-number\">48<\/span> - bits));\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-32\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In Java 5 wurde auf das neue, offizielle <code>java.util.concurrent.atomic<\/code>.<code>AtomicLong<\/code> und dessen <code>compareAndSet()<\/code>-Methode umgestellt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-33\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">import<\/span> java.util.concurrent.atomic.AtomicLong;\n\n<span class=\"hljs-keyword\">private<\/span> AtomicLong seed;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">next<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> bits)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">long<\/span> oldseed, nextseed;\n    AtomicLong seed = <span class=\"hljs-keyword\">this<\/span>.seed;\n    <span class=\"hljs-keyword\">do<\/span> {\n        oldseed = seed.get();\n        nextseed = (oldseed * multiplier + addend) &amp; mask;\n    } <span class=\"hljs-keyword\">while<\/span> (!seed.compareAndSet(oldseed, nextseed));\n    <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-keyword\">int<\/span>)(nextseed &gt;&gt;&gt; (<span class=\"hljs-number\">48<\/span> - bits));\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-33\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In Java 6 wurde die <code>AtomicLong<\/code>-Variable <code>final<\/code> gemacht. Bis Java 18 wurde die Implementierung der <code>next()<\/code>-Methode nicht noch einmal ver\u00e4ndert.<\/p>\n\n\n\n<p>Eine weitere \u00c4nderung gab es an der <code>nextDouble()<\/code>-Methode. Zur Erinnerung \u2013 so sah sie urspr\u00fcnglich aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-34\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">nextDouble<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">long<\/span> l = ((<span class=\"hljs-keyword\">long<\/span>)(next(<span class=\"hljs-number\">26<\/span>)) &lt;&lt; <span class=\"hljs-number\">27<\/span>) + next(<span class=\"hljs-number\">27<\/span>);\n    <span class=\"hljs-keyword\">return<\/span> l \/ (<span class=\"hljs-keyword\">double<\/span>)(<span class=\"hljs-number\">1L<\/span> &lt;&lt; <span class=\"hljs-number\">53<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-34\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Da Division deutlich teurer ist als Multiplikation, wurde in Java 8 der Wert 1\/2<sup>53<\/sup> in eine Konstante extrahiert, und seither wird mit dieser multipliziert:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-35\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">double<\/span> DOUBLE_UNIT = <span class=\"hljs-number\">0x1<\/span><span class=\"hljs-number\">.0<\/span>p-<span class=\"hljs-number\">53<\/span>; <span class=\"hljs-comment\">\/\/ 1.0 \/ (1L &lt;&lt; 53)<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">nextDouble<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> (((<span class=\"hljs-keyword\">long<\/span>)(next(<span class=\"hljs-number\">26<\/span>)) &lt;&lt; <span class=\"hljs-number\">27<\/span>) + next(<span class=\"hljs-number\">27<\/span>)) * DOUBLE_UNIT;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-35\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die Funktionalit\u00e4t der <code>Random<\/code>-Klasse ist also seit Java 1.0 unver\u00e4ndert geblieben; bis Java 8 hat sich allerdings deren Performance kontinuierlich verbessert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"implementierung-von-java-util-concurrent-threadlocalrandom\">Implementierung von java.util.concurrent.ThreadLocalRandom<\/h3>\n\n\n\n<p>In Java 7 liefert die Methode <code>ThreadLocalRandom.current()<\/code> pro Thread eine separate Instanz von <code>ThreadLocalRandom<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-36\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> ThreadLocal&lt;ThreadLocalRandom&gt; localRandom =\n    <span class=\"hljs-keyword\">new<\/span> ThreadLocal&lt;ThreadLocalRandom&gt;() {\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">protected<\/span> ThreadLocalRandom <span class=\"hljs-title\">initialValue<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> ThreadLocalRandom();\n        }\n};\n\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> ThreadLocalRandom <span class=\"hljs-title\">current<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> localRandom.get();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-36\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><code>ThreadLocalRandom<\/code> erbt von <code>Random<\/code>, das den Status in einem <code>AtomicLong<\/code> speichert. Da dessen Threadsicherheit (und der damit einhergehende Overhead) in <code>ThreadLocalRandom<\/code> nicht ben\u00f6tigt werden, speichert <code>ThreadLocalRandom<\/code> den Status stattdessen in einem eigenen Feld <code>rnd<\/code>, auf das es ohne Synchronisation zugreift:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"190\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-600x190.png\" alt=\"ThreadLocalRandom in Java 7: Eine Instanz pro Thread\" class=\"wp-image-27351\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-600x190.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-224x71.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-336x106.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-504x160.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-672x213.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-400x127.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-800x253.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7-944x299.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java7.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">ThreadLocalRandom in Java 7: Eine Instanz pro Thread<\/figcaption><\/figure>\n<\/div>\n\n\n<p>In Java 8 wurde <code>ThreadLocalRandom<\/code> komplett neugeschrieben. Statt separate Instanzen pro Thread bereitzustellen, liefert <code>ThreadLocalRandom.current()<\/code> f\u00fcr alle Threads die gleiche, statische Intanz von <code>ThreadLocalRandom<\/code> zur\u00fcck.<\/p>\n\n\n\n<p>Damit nun nicht alle Threads wieder auf ein- und denselben Status zugreifen (was dann wieder synchronisiert werden m\u00fcsste), wird dieser ab Java 8 in der Variablen <code>threadLocalRandomSeed<\/code> des <code>Thread<\/code>-Objekt des aktuellen Threads gespeichert:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"229\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-600x229.png\" alt=\"ThreadLocalRandom in Java 8: Eine Instanz, Status wird im Thread gespeichert\" class=\"wp-image-27352\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-600x229.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-224x85.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-336x128.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-504x192.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-672x256.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-400x153.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-800x305.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8-944x360.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/ThreadLocalRandom-java8.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">ThreadLocalRandom in Java 8: Eine Instanz, Status wird im Thread gespeichert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Auf dieses Feld wird von <code>ThreadLocalRandom<\/code> aus per <code>jdk.internal.misc.Unsafe<\/code> zugegriffen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-37\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Unsafe U = Unsafe.getUnsafe();\n<span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> SEED\n    = U.objectFieldOffset(Thread<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>, \"<span class=\"hljs-title\">threadLocalRandomSeed<\/span>\")<\/span>;\n\n<span class=\"hljs-comment\">\/\/ ...<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">nextSeed<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    Thread t; <span class=\"hljs-keyword\">long<\/span> r; <span class=\"hljs-comment\">\/\/ read and update per-thread seed<\/span>\n    U.putLong(t = Thread.currentThread(), SEED,\n              r = U.getLong(t, SEED) + (t.getId() &lt;&lt; <span class=\"hljs-number\">1<\/span>) + GOLDEN_GAMMA);\n    <span class=\"hljs-keyword\">return<\/span> r;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-37\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dass verschiedene Threads in Java 7 unterschiedliche und in Java 8 die gleiche <code>ThreadLocalRandom<\/code>-Instanz verwenden, kannst du mit folgendem Beispiel-Code leicht zeigen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-38\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">3<\/span>; i++) {\n  <span class=\"hljs-keyword\">new<\/span> Thread() {\n    <span class=\"hljs-meta\">@Override<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">run<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n      System.out.println(\n          <span class=\"hljs-string\">\"ThreadLocalRandom instance: \"<\/span> + ThreadLocalRandom.current());\n    }\n  }.start();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-38\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Wenn du den Code unter Java 7 laufen l\u00e4sst, siehst du drei unterschiedliche Instanzen; unter Java 8 wird dir dreimal die gleiche Instanz angezeigt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"implementierung-von-java-secure-securerandom\">Implementierung von java.secure.SecureRandom<\/h3>\n\n\n\n<p><code>SecureRandom<\/code> ist selbst keine Implementierung eines sicheren Zufallszahlengenerators. Konkrete Implementierungen werden \u00fcber das Service Provider Interface (SPI) zur Verf\u00fcgung gestellt. Auf diese einzugehen w\u00fcrde den Rahmen dieses Artikels sprengen.<\/p>\n\n\n\n<p>Erw\u00e4hnenswert sind zwei Erweiterungen an <code>SecureRandom<\/code> selbst:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In Java 1.5 wurde die Methode <code>getAlgorithm()<\/code> hinzugef\u00fcgt, die den Namen des implementierten Algorithmus liefert.<\/li>\n\n\n\n<li>In Java 8 kam die Methode <code>getInstanceStrong()<\/code> hinzu, die die Implementierung eines besonders starken Algorihmus liefert, wie er z. B. f\u00fcr RSA-Schl\u00fcsselpaare empfohlen wird.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"enhanced-pseudo-random-number-generators-in-java-17\">\"Enhanced Pseudo-Random Number Generators\" in Java 17<\/h3>\n\n\n\n<p>In Java 17 wurden die Zufallszahlengeneratoren im JDK um eine Interface-Hierarchie erweitert, die zuk\u00fcnftige Erweiterungen erm\u00f6glich soll. Details dazu findest du im <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-17-features\/#Enhanced_Pseudo-Random_Number_Generators\">Artikel \u00fcber Java 17<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fazit\">Fazit<\/h2>\n\n\n\n<p>Dieser Artikel hat damit begonnen die verschiedenen M\u00f6glichkeiten aufzuzeigen, \u00fcber die in Java Zufallszahlen generiert werden k\u00f6nnen.<\/p>\n\n\n\n<p>Danach hast du erfahren, warum Zufallszahlen eigentlich <em>Pseudo<\/em>zufallszahlen sind, wie man eine Folge von Zufallszahlen berechnet und wie man aus zwei gegebenen Zufallszahlen alle zuk\u00fcnftigen Zufallszahlen vorhersagen kann.<\/p>\n\n\n\n<p>Der Artikel hat mit einer Reise durch die Java-Versionen abgeschlossen und darin gezeigt, wie (und warum) die Implementierungen der zuvor gezeigten Methoden im Laufe der Zeit ver\u00e4ndert wurden.<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>Du m\u00f6chtest \u00fcber alle neue Java-Features auf dem Laufenden sein? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>Wie generiert man in Java Zufallszahlen? Wie funktionieren Math.random() und Methoden in Random wie nextInt() und nextDouble()?<\/p>\n<p>Was sind Pseudozufallszahlen? Kann man sie vorhersagen? Wenn ja, wie?<\/p>\n","protected":false},"author":1,"featured_media":34461,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"none","_seopress_titles_title":"","_seopress_titles_desc":"Wie generiert man in Java Zufallszahlen? Wie funktionieren Math.random() und Random? Was sind Pseudozufallszahlen? Kann man sie vorhersagen?","_seopress_robots_index":"","_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":34727,"_post_count":0,"footnotes":""},"categories":[64],"tags":[227,219],"class_list":["post-27034","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-basics-de","tag-java-grundlagen"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/01\/java-random-numbers.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"Wie generiert man in Java Zufallszahlen? Wie funktionieren Math.random() und Methoden in Random wie nextInt() und nextDouble()? Was sind Pseudozufallszahlen? Kann man sie vorhersagen? Wenn ja, wie?","public_identification_id":"2c060ad5479e45c19ad4d589dc34884b","private_identification_id":"e91b6444dc9b478aab07c496f048b148","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/27034","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=27034"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/27034\/revisions"}],"predecessor-version":[{"id":52438,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/27034\/revisions\/52438"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/34461"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=27034"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=27034"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=27034"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}