Apakah valid untuk membagikan satu instance Random
kelas di antara beberapa utas? Dan untuk menelepon nextInt(int)
dari beberapa utas secara khusus?
java
multithreading
random
thread-safety
Shcheklein
sumber
sumber
java.util.concurrent.ThreadLocalRandom
.Jawaban:
Ini adalah utas aman dalam arti masih akan menghasilkan angka acak saat digunakan oleh banyak utas.
Implementasi Sun / Oracle JVM menggunakan sinkronisasi dan AtomicLong sebagai seed untuk meningkatkan konsistensi di seluruh thread. Namun tampaknya tidak dijamin di semua platform dalam dokumentasi.
Saya tidak akan menulis program Anda untuk meminta jaminan seperti itu, terutama karena Anda tidak dapat menentukan urutan
nextInt()
pemanggilan.sumber
Ini aman untuk benang, meskipun tidak selalu.
Lihat http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6362070 untuk detail selengkapnya.
sumber
Menurut dokumentasi, Math.random () menjamin keamanannya untuk digunakan oleh banyak utas. Tetapi kelas Random tidak. Saya berasumsi bahwa Anda harus menyinkronkan itu sendiri.
sumber
Ya, Acak aman untuk thread. yang
nextInt()
metode memanggil dilindunginext(int)
metode yang menggunakanAtomicLong seed, nextseed
(atom panjang) untuk menghasilkan benih berikutnya.AtomicLong
digunakan untuk keamanan benang pada generasi benih.sumber
Seperti yang dikatakan, ini adalah penyimpanan utas, tetapi mungkin bijaksana untuk menggunakan
java.util.concurrent.ThreadLocalRandom
menurut artikel ini (tautan mati). ThreadLocalRandom juga merupakan subkelas dari Random, sehingga kompatibel dengan versi sebelumnya.sumber
Tidak ada alasan mengapa beberapa utas tidak dapat menggunakan semua Acak yang sama. Namun, karena kelas tersebut tidak secara eksplisit aman untuk thread dan mempertahankan urutan nomor pseudo-random melalui seed. Beberapa utas mungkin berakhir dengan nomor acak yang sama. Akan lebih baik untuk membuat beberapa Random untuk setiap utas dan menyemainya secara berbeda.
EDIT : Saya baru saja memperhatikan bahwa implementasi Sun menggunakan AtomicLong jadi saya rasa itu aman untuk Thread (seperti juga dicatat oleh Peter Lawrey (+1)).
EDIT2 : OpenJDK juga menggunakan AtomicLong untuk benih. Seperti yang dikatakan orang lain meskipun masih tidak baik untuk mengandalkan ini.
sumber
Inilah cara saya menangani masalah tanpa mengasumsikan bahwa Random menggunakan variabel atom. Itu masih bisa bertabrakan secara acak jika
currentTime * thread id
sama di masa depan, tapi itu cukup langka untuk kebutuhan saya. Untuk benar-benar menghindari kemungkinan tabrakan, Anda dapat meminta setiap permintaan menunggu stempel waktu jam yang unik.sumber
(24*60*60*1000)
sebagian penting?(24*60*60*1000)
agar utas dengan ID12
dixxxxxxxxxx045
millis tidak diunggulkan sama dengan utas22
dixxxxxxxxxx035
millis. Namun, saya tidak memiliki alasan kuat untuk menganggap bahwa ID utas adalah tambahan, dan tidak ada alasan kuat untuk berpikir saya membuat utas pada waktu yang lebih acak besok daripada hari ini. Saya menyederhanakan alg sekarang dan memperbarui deskripsi untuk mengidentifikasi kekurangannya.The
Random
kelas tidak diatur untuk satu contoh yang akan digunakan dalam beberapa thread. Tentu saja, jika Anda melakukan ini, kemungkinan besar Anda akan meningkatkan kemungkinan menjadi tidak dapat diprediksi dan mendekati angka acak . Tetapi karena ini adalah generator pseudo-random, saya tidak mengerti mengapa Anda perlu membagikan sebuah instance. Apakah ada persyaratan yang lebih spesifik?sumber