2009-06-10 28 views
11

Tôi đã tranh luận điều này với bản thân mình trong vài phút gần đây, và tôi thấy lý do cho cả hai có và không. Điều này xuất phát từ việc nhìn vào các câu trả lời cho Java HashMap vs. Hashtable và thấy một số người nói rằng Hashtable thực tế là chậm hơn.Phương pháp đồng bộ hóa có chậm hơn trong các ứng dụng đơn luồng không?

Dường như với tôi rằng phương pháp đồng bộ nên hành động hoàn toàn không khác với đối tác không đồng bộ của nó nếu chạy trong một chuỗi đơn lẻ, vì hành động đồng bộ hóa sẽ không chặn bất kỳ thứ gì. Điều đó nói rằng, tôi sẽ tưởng tượng trình biên dịch xử lý hai trường hợp khác nhau và đó là lý do tại sao mọi người đang nói đồng bộ là chậm hơn.

Không phải là nó có nghĩa là kết thúc, nhưng tôi đã chạy một số thử nghiệm đơn giản trên HashMap vs Hashtable và thấy sự khác biệt nhỏ về tốc độ.

+1

Nút cổ chai sẽ có trong thuật toán của bạn. Do đó, chi phí đồng bộ hóa nên nhỏ. – sybreon

Trả lời

15

Có, các chương trình Java đơn lẻ được sử dụng đồng bộ hóa có thể hơi chậm hơn so với khi không đồng bộ hóa. Đối với các bản phát hành Java ban đầu, đồng bộ hóa rất tốn kém. Đối với bất kỳ bản phát hành hiện đại nào, tuy nhiên, không được giám sát đồng bộ hóa khá rẻ. Tôi sẽ không lo lắng về điều này.

Lưu ý rằng Java 6 đã và Java 7 là phải có tối ưu hóa tốt xung quanh khóa:

  • Khóa coarsening
  • Khóa sự bỏ bớt
  • thích ứng spin khóa
  • thiên khóa

Để biết thêm thông tin, hãy xem Java SE 6 Performance White Paper. Đồng thời, lưu ý rằng đồng bộ hóa không mong muốn có vẻ đắt hơn trên CPU đa nhân hơn so với CPU đơn lõi, có lẽ do các yêu cầu về Bộ nhớ Java yêu cầu đồng bộ buộc bộ đệm CPU cục bộ được chia sẻ với các CPU khác hoặc một số rào cản bộ nhớ khác. Ví dụ: đọc Do Java 6 threading optimizations actually work? - Part II. (Phần I không sâu sắc như Phần II.)

+0

+1 để đề cập đến tranh chấp - đồng bộ hóa chính nó là giá rẻ. – serg10

+0

@ serg10: Contention? Trong một chương trình luồng đơn? Không. –

5

Có. Họ sẽ được hơi chậm hơn do thêm chi phí của việc duy trì khóa.

+3

chỉ một chút. +1 – sybreon

+0

... NẾU JIT không thể quyết định rằng nó không cần phải duy trì khóa trong trường hợp này ... –

0

Khi sử dụng cấu trúc dữ liệu được đồng bộ hóa, sự chậm lại không phụ thuộc vào "số lượng" bị chặn. Hành động mua hoặc giải phóng khóa là chậm, vì nó thường liên quan đến một cái gì đó giống như một cuộc gọi hệ thống (thiết bị chuyển mạch bối cảnh chậm trên bất kỳ nền tảng nào). Trong môi trường JIT như một JVM điển hình, về mặt lý thuyết có thể tối ưu hóa tất cả các cuộc gọi khóa/mở khóa khi chỉ có một luồng duy nhất đang chạy, nhưng nó sẽ phải được vô hiệu hóa một cách hợp lệ bất cứ khi nào một luồng khác khởi động.

Lưu ý rằng những thứ như futexes của Linux không phải thực hiện cuộc gọi hệ thống trừ khi có tranh chấp, nhưng việc sử dụng chúng vẫn chậm hơn so với no-op.

+0

ngoại trừ nếu hệ điều hành là CPU hot swappable tôi đoán; thì JVM sẽ không thể đưa ra giả định đó? –

+0

Vấn đề không quá nhiều cho dù có nhiều CPU như liệu có nhiều luồng bên trong JVM hay không. Đúng, nhận thức được liệu có nhiều CPU sẽ mở rộng khả năng áp dụng của tối ưu hóa này, nhưng nó phổ biến hơn nhiều để chạy một ứng dụng luồng đơn khi có nhiều CPU. Điểm mà tôi đã cố gắng để vượt qua là tôi không biết bất kỳ mutex tương tự với trường hợp ngoại lệ chi phí bằng không. – user57368

+0

Nếu điều * duy nhất * mà mã của bạn đang thực hiện là lấy và nhả ổ khóa, có, nó sẽ chậm. Miễn là các khóa đủ ít, bất kỳ sự chậm lại nào trong mã của bạn sẽ là tối thiểu, đặc biệt là bất kỳ JVM gần đây nào. Khóa không được kiểm soát không đắt hơn nữa. – Eddie

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