2014-11-07 15 views
6

Hôm nay tôi đã hỏi một câu hỏi trong cuộc phỏng vấn của tôi. Câu hỏi đặt ra là Collections.synchronizedMap() là được sử dụng để đồng bộ hóa bản đồ mặc định không phải là chủ đề an toàn như hashmap. Câu hỏi của ông là nhưng chúng tôi có thể chuyển bất kỳ loại bản đồ nào bên trong phương thức này. Vì vậy, hiệu ứng khi chúng ta vượt qua một hashtable bên trong phương thức này là gì bởi vì hashtable được đồng bộ hóa mặc định.Điều gì sẽ xảy ra khi chúng tôi vượt qua hashtable bên trong Collections.synchronizedMap()

Trả lời

0

Nếu bạn thấy mã trong số SynchronizedCollection.Các phương pháp này sẽ ủy cuộc gọi đến bộ sưu tập cơ bản nhưng thêm đồng bộ khối trên đỉnh của một cái gì đó gọi như

public int size() { 
synchronized (mutex) {return c.size();} 
} 

Việc thực hiện các kích thước trông như thế này trong HashTable lớp này

public synchronized int size() { 
    return count; 
} 

Vì vậy, nếu bạn vượt qua trong HashTable đến SynchronizedCollection, chuỗi truy cập vào SynchronizedCollection sẽ phải lấy khóa ở 2 cấp một lần cho khối được đồng bộ hóa và một cho phương thức được đồng bộ hóa. Nếu có các chủ đề khác bằng cách sử dụng đối tượng HashTable trực tiếp, chúng có thể chặn các luồng bằng cách sử dụng SynchronizedCollection ngay cả khi luồng có khóa trên SynchronizedCollection.

+0

Bản sao câu trả lời của Natix? – user219882

+1

Tôi đã viết câu trả lời song song với anh ấy Tôi nghĩ rằng, tôi không chắc chắn tại sao nó được đặt hàng dưới đây, cộng với tôi đã đưa ra một lý do tại sao không làm điều đó. –

1

Nó sẽ nhận được gói gọn trong một SynchronizedMap, từ java.util.Collections:

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) { 
    return new SynchronizedMap<>(m); 
} 

Các synchronizedMap() phương pháp không phân biệt giữa các loại Map s thông qua vào nó.

2

Bạn sẽ có hai mức độ đồng bộ: một ở mức độ bản đồ đồng bộ chính nó, được thực hiện bởi một đối tượng mutex, và một ở mức độ sơ thẩm gói:

public boolean isEmpty() { 
    // first level synchronization 
    synchronized(mutex) { 
     // second level synchronization if c is a Hashtable 
     return c.isEmpty(); 
    } 
} 

Việc đồng bộ hóa bổ sung là không cần thiết và có thể dẫn đến hiệu suất thấp hơn.

Một hiệu ứng khác là bạn sẽ không thể sử dụng API từ Hashtable như Hashtable#elements kể từ khi bộ sưu tập được bao bọc hoàn toàn là cá thể Map.

3

Hành vi của bản đồ sẽ giống nhau, nhưng hiệu suất sẽ bị ảnh hưởng bởi vì mỗi phương pháp sẽ nhận được hai khóa đồng bộ thay vì một.

Ví dụ: hãy xem xét gọi phương thức size() trên bản đồ kết quả. Việc thực hiện trong lớp Collections.SynchronizedMap trông như thế này:

public int size() { 
    synchronized(mutex) {return m.size();} // first lock 
} 

... ở đâu, m.size() gọi thực hiện trong Hashtable:

public synchronized int size() { // second lock 
    return count; 
} 

Đối tượng khóa đầu tiên là mutex trường trong SynchronizedMap. Khóa thứ hai là ẩn - bản thân ví dụ Hashtable.

0

"Câu hỏi của anh ấy là chúng tôi có thể chuyển bất kỳ loại bản đồ nào bên trong phương thức này".

Câu trả lời là có, bởi vì hàm tạo của SynchronizedMap chấp nhận mọi chữ ký Map trong chữ ký của nó.

"Vì vậy, hiệu quả là những gì khi chúng ta vượt qua một Hashtable bên trong phương pháp này vì Hashtable là theo mặc định đồng bộ"

Câu trả lời là: Chúng tôi đang thể hiện sự thiếu hiểu biết đến ConcurrentHashMap được nhiều khả năng công cụ được sử dụng thay vì về việc triển khai chặn.

Các vấn đề liên quan