Các thuật toán chính về cơ bản giống nhau. ThreadLocalRandom sử dụng cấu trúc Java ThreadLocal để tạo một biến ngẫu nhiên mới cho mỗi luồng. Điều này đảm bảo rằng các cuộc gọi từ mỗi thread sẽ không bao giờ xung đột với mỗi (không tranh chấp).
Hãy nhìn vào dòng này từ ngẫu nhiên để so sánh:
} while (!seed.compareAndSet(oldseed, nextseed));
Khi bạn yêu cầu một giá trị tới, ngẫu nhiên có giá trị cũ và tạo ra một giá trị mới. Sau đó, nó sử dụng hàm AtomicLong.compareAndSet để đặt giá trị mới, chỉ khi giá trị cũ vẫn là giá trị được sử dụng. Nếu một luồng khác đã thay đổi giá trị, vòng lặp sẽ chạy lại (và một lần nữa, cho đến khi nó là vòng lặp duy nhất vừa nhận được vừa thiết lập giá trị trong một thế hệ số ngẫu nhiên). Vì vậy, có thể tranh chấp, và do đó có thể có hiệu quả tác động.
ThreadLocalRandom, bởi vì nó được đảm bảo không xung đột, không yêu cầu chức năng nguyên tử và thao tác/khóa an toàn chỉ.
Có một số sự cân bằng mà bạn muốn suy nghĩ. Sử dụng một Random cho phép một bộ tạo số ngẫu nhiên rất hữu ích nếu bạn muốn sử dụng một hạt giống duy nhất cho ứng dụng của bạn. Nếu bạn thỉnh thoảng thực hiện các cuộc gọi ngẫu nhiên, để xung đột có thể là "hiếm" (không phải trường hợp bình thường) thì bạn có thể không lo lắng về xung đột và tác động nhỏ đến hiệu suất có thể không quan trọng. Nếu bạn đang gọi ngẫu nhiên hàng trăm thời gian mỗi giây trên nhiều luồng, thì bạn rõ ràng muốn sử dụng ThreadLocalRandom.
Nếu tôi tạo một thể hiện mới của java.util.Random trong mỗi chuỗi, nó sẽ không dẫn đến hiệu ứng giống như sử dụng ThreadLocalRandom trong mỗi luồng không? Hoặc làm tất cả các trường hợp của java.util.Random sử dụng cùng một hạt giống? – Peter
Một phần của vấn đề với 'Ngẫu nhiên' là không cần thiết' đồng bộ hóa '; ngay cả khi bạn tạo một chuỗi cho mỗi luồng, nó sẽ không được thực hiện như 'ThreadLocalRandom'. – dimo414