Chủ đề lớp ngẫu nhiên có an toàn không?


110

Có hợp lệ để chia sẻ một phiên bản của Randomlớp giữa nhiều luồng không? Và để gọi nextInt(int)từ nhiều chủ đề cụ thể?


@Bala R, không, chúng ta không nói về đối tượng Ngẫu nhiên của C # mà là của Java.
Buhake Sindi

Giáo sư. xin lỗi đã bỏ lỡ phần đó.
Bala R

Việc quan tâm đến việc sử dụng Ngẫu nhiên để lấy các số trong môi trường đa luồng có thể mang lại cho bạn kết quả không tốt, có thể không thành vấn đề nhưng nếu bạn đang thực hiện một số mô phỏng thì bạn nên biết.
Maxence SCHMITT

14
Đối với độc giả xa hơn: có một lớp mới với 1.7 được đặt tên java.util.concurrent.ThreadLocalRandom.
Jin Kwon

Câu trả lời:


66

Nó là một chuỗi an toàn theo nghĩa nó sẽ vẫn tạo ra các số ngẫu nhiên khi được sử dụng bởi nhiều chủ đề.

Việc triển khai Sun / Oracle JVM sử dụng đồng bộ hóa và AtomicLong làm hạt giống để cải thiện tính nhất quán giữa các luồng. Nhưng nó dường như không được đảm bảo trên tất cả các nền tảng trong tài liệu.

Tôi sẽ không viết chương trình của bạn để yêu cầu đảm bảo như vậy, đặc biệt là khi bạn không thể xác định thứ tự nextInt()sẽ được gọi.


69
Một đảm bảo đã được thêm vào tài liệu Java 7: "Các phiên bản của java.util.Random là luồng an toàn." docs.oracle.com/javase/7/docs/api/java/util/Random.html
Matt R


8

Theo tài liệu, Math.random () đảm bảo rằng nó an toàn cho nhiều luồng sử dụng. Nhưng lớp Random thì không. Tôi giả sử rằng bạn sẽ phải tự đồng bộ hóa điều đó.


7

Có, Ngẫu nhiên là chủ đề an toàn. các nextInt()phương pháp gọi là bảo vệ next(int)phương pháp mà sử dụng AtomicLong seed, nextseed(nguyên tử dài) để tạo ra một hạt giống tiếp theo. AtomicLongđược sử dụng để đảm bảo an toàn cho sợi khi tạo hạt.


6

Như đã nói, nó là lưu chủ đề, nhưng nó có thể là khôn ngoan khi sử dụng java.util.concurrent.ThreadLocalRandomtheo bài viết này (liên kết chết). ThreadLocalRandom cũng là một lớp con của Random, vì vậy nó tương thích ngược.

Bài báo hình liên kết nào so sánh profiling kết quả của lớp Random khác nhau: java.util.Random, java.util.concurrent.ThreadLocalRandomjava.lang.ThreadLocal<java.util.Random>. Kết quả cho thấy rằng việc sử dụng ThreadLocalRandom là hiệu quả nhất, tiếp theo là ThreadLocal và bản thân Random hoạt động kém nhất.


4

Không có lý do gì nhiều chủ đề không thể sử dụng cùng một Ngẫu nhiên. Tuy nhiên, vì lớp không an toàn theo luồng rõ ràng và duy trì một chuỗi các số giả ngẫu nhiên thông qua hạt giống. Nhiều chủ đề có thể kết thúc với cùng một số ngẫu nhiên. Sẽ tốt hơn nếu tạo nhiều Ngẫu nhiên cho mỗi chủ đề và gieo chúng theo cách khác nhau.

CHỈNH SỬA : Tôi vừa nhận thấy rằng việc triển khai Sun sử dụng AtomicLong nên tôi đoán rằng điều đó là an toàn cho Thread (như Peter Lawrey đã lưu ý (+1)).

EDIT2 : OpenJDK cũng sử dụng AtomicLong cho hạt giống. Như những người khác đã nói mặc dù vẫn không tốt nếu dựa vào điều này.


3

Đây là cách tôi xử lý vấn đề mà không giả định rằng Random sử dụng các biến nguyên tử. Nó vẫn có thể va chạm ngẫu nhiên nếu currentTime * thread idbằng nhau vào một thời điểm nào đó trong tương lai, nhưng điều đó đủ hiếm đối với nhu cầu của tôi. Để thực sự tránh được khả năng xảy ra va chạm, bạn có thể yêu cầu mỗi yêu cầu chờ một dấu thời gian đồng hồ duy nhất.

/**
 * Thread-specific random number generators. Each is seeded with the thread
 * ID, so the sequence of pseudo-random numbers are unique between threads.
 */
private static ThreadLocal<Random> random = new ThreadLocal<Random>() {
    @Override
    protected Random initialValue() {
        return new Random(
            System.currentTimeMillis() *
            Thread.currentThread().getId());
    }
};

Lên! Q: là (24*60*60*1000)một phần đáng kể?
Jin Kwon

1
Vâng, đó là một sửa chữa bẩn. Đó (24*60*60*1000)là để một luồng có ID 12xxxxxxxxxx045mili không bị bắt giống như một luồng 22xxxxxxxxxx035mili. Tuy nhiên, tôi không có bất kỳ lý do chính đáng nào để cho rằng ID chuỗi ngày càng tăng và không có lý do chính đáng để nghĩ rằng ngày mai tôi đang tạo chuỗi vào những thời điểm ngẫu nhiên hơn hôm nay. Tôi đã đơn giản hóa alg ngay bây giờ và cập nhật mô tả để xác định thiếu sót.
Ryan

0

Các Randomlớp học không được thiết lập cho một trường hợp được sử dụng trong nhiều chủ đề. Tất nhiên, nếu bạn đã làm điều này, có khả năng bạn sẽ tăng khả năng nhận được những con số ngẫu nhiên không thể đoán trước và gần hơn . Nhưng vì nó là một trình tạo giả ngẫu nhiên, tôi không thể hiểu tại sao bạn cần chia sẻ một phiên bản. Có yêu cầu cụ thể hơn không?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.