Câu trả lời:
đồng bộ HashMap
:
Mỗi phương thức được đồng bộ hóa bằng cách sử dụng khóa cấp đối tượng. Vì vậy, các phương thức get và put trên synchMap có được một khóa.
Khóa toàn bộ bộ sưu tập là một chi phí hiệu suất. Trong khi một luồng giữ khóa, không có luồng nào khác có thể sử dụng bộ sưu tập.
ConcurrentHashMap
đã được giới thiệu trong JDK 5.
Không có khóa ở cấp đối tượng, Khóa ở mức độ chi tiết tốt hơn nhiều. Đối với a ConcurrentHashMap
, các khóa có thể ở mức găm băm.
Tác dụng của khóa cấp thấp hơn là bạn có thể có các trình đọc và ghi đồng thời không thể có cho các bộ sưu tập được đồng bộ hóa. Điều này dẫn đến khả năng mở rộng hơn nhiều.
ConcurrentHashMap
không ném ConcurrentModificationException
nếu một chủ đề cố gắng sửa đổi nó trong khi một chủ đề khác đang lặp lại trên nó.
Bài viết này Java 7: HashMap vs ConcảnHashMap là một bài đọc rất tốt. Rất khuyến khích.
ConcurrentHashMap
là size()
kết quả của nó có thể bị lỗi thời. size()
được phép trả về một xấp xỉ thay vì một số đếm chính xác theo cuốn sách "Đồng thời Java trong thực tiễn". Vì vậy phương pháp này nên được sử dụng cẩn thận.
Câu trả lời ngắn gọn:
Cả hai bản đồ là các triển khai an toàn chủ đề của Map
giao diện. ConcurrentHashMap
được thực hiện cho thông lượng cao hơn trong trường hợp dự kiến đồng thời cao.
Bài viết của Brian Goetz về ý tưởng đằng sau ConcurrentHashMap
là một bài đọc rất hay. Rất khuyến khích.
Map m = Collections.synchronizedMap(new HashMap(...));
docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
ConcurrentHashMap
là chủ đề an toàn mà không đồng bộ hóa toàn bộ bản đồ. Đọc có thể xảy ra rất nhanh trong khi viết được thực hiện với một khóa.
Chúng ta có thể đạt được sự an toàn của luồng bằng cách sử dụng cả ConcảnHashMap và đồng bộ hóa. Nhưng có rất nhiều sự khác biệt nếu bạn nhìn vào kiến trúc của họ.
Nó sẽ duy trì khóa ở cấp đối tượng. Vì vậy, nếu bạn muốn thực hiện bất kỳ thao tác nào như đặt / nhận thì trước tiên bạn phải có được khóa. Đồng thời, các luồng khác không được phép thực hiện bất kỳ hoạt động nào. Vì vậy, tại một thời điểm, chỉ có một luồng có thể hoạt động trên này. Vì vậy, thời gian chờ đợi sẽ tăng lên ở đây. Chúng tôi có thể nói rằng hiệu suất tương đối thấp khi bạn so sánh với ConcảnHashMap.
Nó sẽ duy trì khóa ở cấp phân khúc. Nó có 16 phân đoạn và duy trì mức đồng thời là 16 theo mặc định. Vì vậy, tại một thời điểm, 16 luồng có thể có thể hoạt động trên ConcảnHashMap. Hơn nữa, hoạt động đọc không yêu cầu khóa. Vì vậy, bất kỳ số lượng chủ đề có thể thực hiện một hoạt động có được trên nó.
Nếu thread1 muốn thực hiện thao tác put trong phân đoạn 2 và thread2 muốn thực hiện thao tác put trên phân khúc 4 thì nó được phép ở đây. Có nghĩa là, 16 luồng có thể thực hiện thao tác cập nhật (đặt / xóa) trên ConcảnHashMap tại một thời điểm.
Vì vậy, thời gian chờ đợi sẽ ít hơn ở đây. Do đó hiệu suất tương đối tốt hơn so với đồng bộ hóa.
Cả hai đều là phiên bản đồng bộ của HashMap, với sự khác biệt về chức năng cốt lõi và cấu trúc bên trong của chúng.
ConcảnHashMap bao gồm các phân đoạn nội bộ có thể được xem là HashMaps độc lập về mặt khái niệm. Tất cả các phân đoạn như vậy có thể bị khóa bởi các luồng riêng biệt trong các thực thi đồng thời cao. Vì vậy, nhiều luồng có thể nhận / đặt các cặp khóa-giá trị từ ConcảnHashMap mà không chặn / chờ nhau. Điều này được thực hiện cho thông lượng cao hơn.
trong khi
Bộ sưu tập.syn syncizedMap () , chúng tôi nhận được một phiên bản HashMap được đồng bộ hóa và nó được truy cập theo cách chặn. Điều này có nghĩa là nếu nhiều luồng cố gắng truy cập đồng bộ hóa cùng một lúc, chúng sẽ được phép nhận / đặt các cặp khóa-giá trị một lần theo cách đồng bộ hóa.
ConcurrentHashMap
sử dụng cơ chế khóa chi tiết hơn được gọi là lock stripping
cho phép mức độ truy cập được chia sẻ lớn hơn. Do đó, nó cung cấp khả năng đồng thời và khả năng mở rộng tốt hơn .
Ngoài ra các trình lặp được trả về ConcurrentHashMap
là nhất quán yếu thay vì thất bại kỹ thuật nhanh được sử dụng bởi HashMap được đồng bộ hóa.
Bản đồ đồng thời:
1) Cả hai bản đồ đều là các triển khai an toàn theo luồng của giao diện Bản đồ.
2) ConcảnHashMap được triển khai cho thông lượng cao hơn trong trường hợp dự kiến đồng thời cao.
3) Không có khóa trong cấp đối tượng.
Bản đồ Hash được đồng bộ hóa:
1) Mỗi phương thức được đồng bộ hóa bằng cách sử dụng khóa cấp đối tượng.
Đồng thờiHashMap cho phép truy cập dữ liệu đồng thời. Toàn bộ bản đồ được chia thành các phân khúc.
Đọc hoạt động tức là. get(Object key)
không được đồng bộ ngay cả ở cấp phân khúc.
Nhưng viết thao tác tức là. remove(Object key), get(Object key)
có được khóa ở cấp phân khúc. Chỉ một phần của toàn bản đồ bị khóa, các luồng khác vẫn có thể đọc các giá trị từ các phân đoạn khác nhau ngoại trừ bị khóa.
SynchronizedMap Mặt khác, khóa Acquire ở mức đối tượng. Tất cả các luồng nên chờ cho luồng hiện tại bất kể hoạt động (Đọc / Ghi).
Một thử nghiệm hiệu năng đơn giản cho ConcảnHashMap so với HashMap được Đồng bộ hóa
. Luồng kiểm tra đang gọi put
trong một luồng và gọi đồng thời get
ba luồng Map
. Như @trshiv đã nói, ConcảnHashMap có thông lượng và tốc độ cao hơn cho hoạt động đọc mà không cần khóa. Kết quả là khi thời gian hoạt động kết thúc 10^7
, ConcảnHashMap 2x
nhanh hơn HashMap được Đồng bộ hóa.
SynchronizedMap
và ConcurrentHashMap
đều là lớp an toàn của luồng và có thể được sử dụng trong ứng dụng đa luồng, sự khác biệt chính giữa chúng là về cách chúng đạt được an toàn luồng.
SynchronizedMap
có được khóa trên toàn bộ đối tượng Bản đồ, trong khi ConcurrentHashMap
chia đối tượng Bản đồ thành nhiều phân đoạn và việc khóa được thực hiện trên các đối tượng đó.
Theo tài liệu java
Hashtable và Collections.syn syncizedMap (HashMap mới ()) được đồng bộ hóa. Nhưng ConcảnHashMap là "đồng thời".
Một bộ sưu tập đồng thời là an toàn luồng, nhưng không bị chi phối bởi một khóa loại trừ duy nhất.
Trong trường hợp cụ thể của ConcảnHashMap, nó cho phép một cách an toàn bất kỳ số lần đọc đồng thời cũng như số lần ghi đồng thời có thể điều chỉnh. Các lớp "được đồng bộ hóa" có thể hữu ích khi bạn cần ngăn tất cả quyền truy cập vào bộ sưu tập thông qua một khóa duy nhất, với chi phí khả năng mở rộng kém hơn.
Trong các trường hợp khác trong đó nhiều luồng dự kiến sẽ truy cập vào một bộ sưu tập chung, các phiên bản "đồng thời" thường được ưa thích hơn. Và các bộ sưu tập không đồng bộ được ưu tiên hơn khi các bộ sưu tập không được chia sẻ hoặc chỉ có thể truy cập khi giữ các khóa khác.
Hashtable
và làSynchronized HashMap
gì?