{"id":1925,"date":"2013-06-07T20:32:58","date_gmt":"2013-06-07T18:32:58","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=1925"},"modified":"2013-06-07T20:32:58","modified_gmt":"2013-06-07T18:32:58","slug":"threadlocalrandom-als-schneller-paralleler-zufallszahlengenerator","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2013\/06\/threadlocalrandom-als-schneller-paralleler-zufallszahlengenerator\/","title":{"rendered":"ThreadLocalRandom als schneller paralleler Zufallszahlengenerator"},"content":{"rendered":"<p>Zufallszahlen sind immer nur Pseudozufallszahlen und werden mit einer mathematischen Formel aus dem Vorg\u00e4nger generiert. Der Vorg\u00e4nger muss dabei gespeichert werden, und das ist die Aufgabe eines Random-Objekts. Die Methode Math.random() nutzt intern ein Random-Objekt, und jetzt kann es zu Wartezeiten kommen, wenn mehrere Threads gleichzeitig random() aufrufen, denn die Methode darf intern ja nur einen Thread die letzte Zufallszahl schreiben lassen. Math ist also eine Klasse mit Zustand und Zustandsverwaltung ist bei Multithreaded-Anwendungen immer etwas speziell.<\/p>\n<p>Um Zufallszahlen schnell generieren zu k\u00f6nnen, sind diese Verz\u00f6gerungen ung\u00fcnstig, und es gibt zwei L\u00f6sungen daf\u00fcr. Einmal l\u00e4sst sich pro Thread ein Random-Objekt generieren, sodass es im Code der Random-Klasse dann keine Konkurrenzsituation geben kann. Aber optimal ist das noch nicht, denn der Programmcode der Random-Klasse ist auf diese Nebenl\u00e4ufigkeit vorbereitet, und bei nur einem Thread w\u00e4re ein schlankerer Programmcode besser, der f\u00fcr eine Single-Threaded Abarbeitung optimiert ist. Und hier kommt die Klasse java.util.concurrent.ThreadLocalRandom ins Spiel. Sie ist eine Unterklasse von Random und \u00fcberschreibt die eigentliche Generator-Methode next(int)-Methode so, dass es keine Synchronisation gibt; die Ausf\u00fchrung in Multithreaded-Umgebung ist dementsprechend schnell.<\/p>\n<p>Beispiel: Erzeuge Zufallszahlen zwischen 1 und 10:<\/p>\n<p>ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();   <br \/>System.out.println( threadLocalRandom.nextInt( 1, 10 + 1 ) );    <br \/>System.out.println( threadLocalRandom.nextInt( 1, 10 + 1 ) );<\/p>\n<p>Die Variable threadLocalRandom kann problemlos zwischen verschiedenen Threads \u201egeteilt\u201c werden.<\/p>\n<p>Die Klasse ThreadLocalRandom erbt alle Methoden von Random, und \u00fcberschreibt etwa die neuen Methoden aus Java 8, die einen Stream von Zufallszahlen liefern. Desweiteren kommen einige neue Methoden hinzu, um etwa Zufallszahlen in einem gewissen Bereich zu generieren \u2013 das fehlt in Random. Ein neuer Seed kann nicht gesetzt werden, ThreadLocalRandom \u00fcberschreibt setSeed(long) so, dass eine UnsupportedOperationException ausgel\u00f6st wird.<\/p>\n<p>class java.util.concurrent.<b>ThreadLocalRandom<\/b>    <br \/>extends Random<\/p>\n<p>\u00a7 static ThreadLocalRandom current()   <br \/>Liefert das aktuelle ThreadLocalRandom-Objekt.<\/p>\n<p>\u00a7 void setSeed(long seed)   <br \/>Nicht unterst\u00fctzt, l\u00f6st UnsupportedOperationException aus.<\/p>\n<p>\u00a7 double nextDouble(double n)<\/p>\n<p>\u00a7 double nextDouble(double least, double bound)<\/p>\n<p>\u00a7 double nextGaussian()<\/p>\n<p>\u00a7 int nextInt(int least, int bound)<\/p>\n<p>\u00a7 long nextLong(long n)<\/p>\n<p>\u00a7 long nextLong(long least, long bound)   <br \/>Liefert Zufallszahl und aktualisiert den Seed.<\/p>\n<p>\u00a7 DoubleStream doubles()<\/p>\n<p>\u00a7 IntStream ints()<\/p>\n<p>\u00a7 LongStream longs()<\/p>\n<p>\u00a7 DoubleStream gaussians()   <br \/>Liefert einen Stream von Daten.<\/p>\n<p>\u00a7 protected int next(int bits)   <br \/>Liefert die n\u00e4chste Zufallszahl, eine interne Methode, die ThreadLocalRandom aus Random \u00fcberschreibt und protected bel\u00e4sst.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Zufallszahlen sind immer nur Pseudozufallszahlen und werden mit einer mathematischen Formel aus dem Vorg\u00e4nger generiert. Der Vorg\u00e4nger muss dabei gespeichert werden, und das ist die Aufgabe eines Random-Objekts. Die Methode Math.random() nutzt intern ein Random-Objekt, und jetzt kann es zu Wartezeiten kommen, wenn mehrere Threads gleichzeitig random() aufrufen, denn die Methode darf intern ja nur [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11,66],"tags":[],"class_list":["post-1925","post","type-post","status-publish","format-standard","hentry","category-insel","category-java-8"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=1925"}],"version-history":[{"count":0,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1925\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=1925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=1925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=1925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}