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
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
.
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ó.
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
.
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
.
"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.
- 1. Điều gì sẽ xảy ra khi tôi biên dịch?
- 2. Điều gì sẽ xảy ra khi chúng tôi đặt Xmx và Xms bằng kích thước
- 3. Điều gì sẽ xảy ra sau khi gói bị bắt?
- 4. Điều gì sẽ xảy ra nếu tôi ReleaseMutex() hai lần?
- 5. điều gì sẽ xảy ra nếu chúng tôi không giải quyết hoặc từ chối lời hứa
- 6. Điều gì sẽ xảy ra khi va chạm băm xảy ra trong khóa Từ điển?
- 7. Điều gì sẽ xảy ra khi viết không được ghi vượt qua ranh giới trang và lỗi được kích hoạt?
- 8. Điều gì sẽ xảy ra nếu chúng tôi đặt giá trị không xác định?
- 9. Điều gì sẽ xảy ra khi ném ngoại lệ C++?
- 10. Điều gì sẽ xảy ra với QueueWorker khi TTR hết?
- 11. Điều gì sẽ xảy ra khi mongodb hết bộ nhớ?
- 12. Điều gì sẽ xảy ra khi Stack và Heap Collide
- 13. Điều gì sẽ xảy ra trong mệnh đề 'cond' của Đề án khi bỏ qua 'else'?
- 14. Điều gì sẽ xảy ra khi chúng tôi truy cập thuộc tính 'Độ dài' của chuỗi trong C#?
- 15. Sự khác nhau giữa Hashtable và Collections.synchronizedMap (HashMap)
- 16. Điều gì sẽ xảy ra khi tôi làm chủ gốc git pull trong nhánh phát triển?
- 17. Điều gì sẽ xảy ra trong Oracle khi tôi thả một cột?
- 18. Điều gì sẽ xảy ra khi có mã bên dưới $ location.path ('new/path')?
- 19. Điều gì xảy ra khi chúng tôi không chỉ định <meta charset = "utf-8">?
- 20. điều gì sẽ xảy ra khi tôi trộn các loại đã ký và chưa ký?
- 21. Điều gì sẽ xảy ra trong Rust khi sử dụng "match" nếu không có gì khớp?
- 22. Điều gì xảy ra dưới mui xe khi chúng tôi thực hiện presentViewController?
- 23. Điều gì sẽ xảy ra với AsyncTasks sau onPause?
- 24. Điều gì sẽ xảy ra với chức năng nội tuyến bên ngoài?
- 25. Điều gì sẽ xảy ra với ổ cắm khi tôi rút cáp mạng?
- 26. Điều gì sẽ xảy ra nếu kích thước của chuỗi bể vượt quá?
- 27. Điều gì xảy ra khi chúng tôi kết hợp RAII và GOTO?
- 28. Điều gì sẽ xảy ra khi tôi khởi động lại phiên bản EC2?
- 29. Điều gì sẽ xảy ra với JS ServiceWorker khi tôi đóng tab
- 30. Điều gì sẽ xảy ra khi tôi chuyển đối số cho biểu tượng Clojure?
Bản sao câu trả lời của Natix? – user219882
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 đó. –