Đó là vì chuỗi sẽ được thực thi thứ hai là đặt giá trị data
trước khi chuỗi đầu tiên in bất kỳ thứ gì. Thực hiện một thay đổi nhỏ để mã của bạn minh họa điều này khá tốt:
public final class ThinkThreadLocal {
public static int data;
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
int temp = data = new Random().nextInt();
System.out.println(Thread.currentThread().getName() + " temp: " + temp);
System.out.println(Thread.currentThread().getName() + " shared: " + data);
}
}).start();
}
}
}
Một thực hiện này đã cho tôi:
Thread-0 temp: 709919531
Thread-1 temp: 2022218312
Thread-0 shared: 2022218312
Thread-1 shared: 2022218312
Như bạn có thể thấy, các giá trị được tạo ra là khác nhau (709.919.531 và 2022218312 trong này trường hợp), nhưng data
đang được ghi đè bằng giá trị thứ hai trước khi giá trị đầu tiên được in. Điều này cho thấy nó không liên quan đến hạt giống của Random
.
Một cách thứ hai để hiển thị này là để đồng bộ hóa trên lớp chính nó, mà (trong trường hợp này) sẽ chặn các chủ đề đó được thực hiện thứ hai cho đến khi là người đầu tiên đã hoàn tất thi công:
public final class ThinkThreadLocal {
public static int data;
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
synchronized (ThinkThreadLocal.class) {
data = new Random().nextInt();
System.out.println(Thread.currentThread().getName() + " shared: " + data);
}
}
}).start();
}
}
}
mà dẫn đến
Thread-0 shared: 1811879710
Thread-1 shared: 1738616729
@ saka1029 có, nhưng nếu bạn tạo Random với hàm tạo mặc định, chúng sẽ không được tạo với cùng một hạt giống. –