Đồng thờiHashMap so với HashMap được đồng bộ hóa


148

Sự khác biệt giữa việc sử dụng lớp bao bọc SynchronizedMap, trên một HashMapvà là ConcurrentHashMapgì?

Có phải nó chỉ có thể sửa đổi HashMaptrong khi lặp lại nó ( ConcurrentHashMap)?

Câu trả lời:


120

đồng bộ HashMap:

  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. Vì vậy, các phương thức get và put trên synchMap có được một khóa.

  2. 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.

  1. 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.

  2. 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.

  3. ConcurrentHashMapkhông ném ConcurrentModificationExceptionnế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.


7
Vậy sự khác biệt giữa Hashtablevà là Synchronized HashMapgì?
roottraveller

1
Giữa một Bản đồ đồng thời và Bản đồ đồng bộ hóa, bạn muốn giới thiệu cái nào?
Blunderchips

2
Điều đáng nói ConcurrentHashMapsize()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.
Andrii Lisun

1
@roottraveller cho Hashtable và đồng bộ hóa HashMap stackoverflow.com/questions/8875680/
Narendra Jaggi

89

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 Mapgiao 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 ConcurrentHashMaplà một bài đọc rất hay. Rất khuyến khích.


1
Đây là cái gì vậy? HashMap: Lưu ý rằng việc triển khai này không được đồng bộ hóa để ngăn chặn sự truy cập không đồng bộ ngẫu nhiên vào bản đồ: Map m = Collections.synchronizedMap(new HashMap(...)); docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
X-HuMan

5
"Bài viết của Brian Goetz ... là một bài đọc rất hay." - Và hơn thế nữa là cuốn sách "Java đồng thời trong thực tiễn" của ông.
Alex Fedulov

31

ConcurrentHashMaplà 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.


18

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ọ.

  1. đồng bộ hóa

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.

  1. Bản đồ đồng thời

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.


Lời giải thích rất hay Cảm ơn rất nhiều
amoljdv06

11

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.


7

ConcurrentHashMapsử dụng cơ chế khóa chi tiết hơn được gọi là lock strippingcho phép mức độ truy cập được chia sẻ lớn hơn. Do đó, nó cung cấp khả năng đồng thờikhả năng mở rộng tốt hơn .

Ngoài ra các trình lặp được trả về ConcurrentHashMapnhấ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.


3

Các phương thức SynchronizedMapgiữ khóa trên đối tượng, trong khi đó, trong ConcurrentHashMapkhái niệm "khóa dải" trong đó các khóa được giữ trên các thùng của nội dung thay thế. Do đó cải thiện khả năng mở rộng và hiệu suất.


2

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.


1

Đồ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).


1

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 puttrong một luồng và gọi đồng thời getba 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 2xnhanh hơn HashMap được Đồng bộ hóa.


1

SynchronizedMapConcurrentHashMapđề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.

SynchronizedMapcó được khóa trên toàn bộ đối tượng Bản đồ, trong khi ConcurrentHashMapchia đố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 đó.

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


0

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.

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.