Bản thân tham gia (của ForkJoin) yêu cầu điểm đồng bộ hóa, đó là phần thông tin quan trọng nhất. Một điểm đồng bộ sẽ đảm bảo rằng tất cả các ghi xảy ra đều có thể nhìn thấy sau điểm được nói.
Nếu bạn xem mã, bạn có thể thấy nơi xảy ra điểm đồng bộ hóa. Đây chỉ là một cuộc gọi phương thức invokeAll
public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
t2.fork();
t1.invoke();
t2.join();
}
Tại đây t2 tiến hành một quá trình khác, t1 thực hiện nhiệm vụ của nó và chuỗi đang chờ sẽ chờ t2.join(). Khi vượt qua t2. Tất cả ghi vào t1 và t2 sau đó sẽ được hiển thị.
Chỉnh sửa: Chỉnh sửa này chỉ nhằm cung cấp thêm một chút giải thích về ý nghĩa của tôi bằng điểm đồng bộ hóa.
Cho phép nói rằng bạn có hai biến
int x;
volatile int y;
Bất cứ lúc nào bạn viết thư cho y tất cả viết đã xảy ra trước khi bạn đọc y sẽ có sẵn. Ví dụ
public void doWork(){
x = 10;
y = 5;
}
Nếu thread khác đọc y = 5 mà chủ đề là đảm bảo để đọc x = 10. Điều này là do ghi vào y tạo ra một điểm đồng bộ hóa trong đó tất cả viết trước khi nói điểm sẽ có thể nhìn thấy sau khi viết.
Với nhóm Tham gia ngã ba, sự tham gia của ForkJoinTask sẽ tạo một điểm đồng bộ hóa. Bây giờ, nếu t2.fork() và t1.invoke(), việc nối của t2 sẽ đảm bảo rằng tất cả các bài viết mà trước đây đã xảy ra sẽ được nhìn thấy. Vì tất cả các bài viết trước đều nằm trong cùng một cấu trúc, nó sẽ an toàn cho khả năng hiển thị.
Tôi rất sẵn lòng giải thích thêm nếu điều đó không rõ ràng.
Nguồn
2011-01-26 01:34:27
Chúng hoạt động trên các phần khác nhau của mảng. Không có tranh chấp cho đến khi sáp nhập. –
Tôi đồng ý rằng họ đang hoạt động trên các phần khác nhau. Nhưng ngữ nghĩa của mô hình bộ nhớ của Java nhiều hay ít nói rằng không phải tất cả các luồng đều được đảm bảo để xem tất cả các ghi (trừ khi biến là biến động). Theo blog này: http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html thậm chí sử dụng một int dễ bay hơi [] là không đủ để đảm bảo rằng các chủ đề khác nhìn thấy ghi của bạn vào mảng –