2015-07-04 15 views
7

synchronized không phải là một phần của chữ ký phương thức. Nhưng khi chúng ta ghi đè lên một phương thức, nó không chỉ là chữ ký phương thức mà quyết định liệu phương thức ghi đè sẽ biên dịch hay không.Tại sao "đồng bộ hóa" không có vai trò trong đa hình

Ví dụ, chúng ta không thể thêm hoặc mở rộng một ngoại lệ kiểm tra

Tại sao synchronized không có vai trò trong việc đa hình. Không nên ghi đè phương thức synchronized mà không đặt synchronized. Vì người đang sử dụng biến siêu lớp có thể nghĩ rằng tất cả các phương thức đều là an toàn.

Nhưng phương pháp không được đồng bộ hóa sẽ được phép ghi đè bằng synchronized vì nó đang thêm nhiều chức năng hơn nhưng mặt khác người dùng sẽ không gặp phải bất kỳ lỗi nào ngoại trừ thời gian trễ.

Tôi đang tìm một giải thích hợp lý có thể ném một số ánh sáng lên "tại sao được thiết kế như vậy".

Trả lời

5

Bạn có thể xem JDK-4294756 để được giải thích về việc đó là phương pháp ghi đè lên phương thức khác mà không cần giữ lại công cụ sửa đổi synchronized. Báo cáo lỗi này yêu cầu trình biên dịch hiển thị cảnh báo khi phương thức ghi đè phương thức synchronized nhưng không tự khai báo synchronized và được đóng là "Không khắc phục". Lý do chính là như sau:

Việc sử dụng sửa đổi đồng bộ, cũng như đồng bộ hóa khác qua tuyên bố 'đồng bộ' rõ ràng, là một phần của việc thực hiện một sự trừu tượng đại diện bởi một lớp, và một thực hiện thay thế được chụp trong một phân lớp có thể sử dụng một chiến lược đồng bộ hóa khác để thực hiện ngữ nghĩa tương đương. Ví dụ, xem xét trường hợp trong đó phần quan trọng nhỏ (được bảo vệ bằng câu lệnh 'đồng bộ') trong phương thức không đồng bộ lớn hơn thay thế một phương thức nhỏ hơn được bảo vệ trong toàn bộ công cụ sửa đổi phương thức được đồng bộ hóa của nó .

Vì vậy, thiếu bộ sửa đổi synchronized không nhất thiết có nghĩa là phương pháp không an toàn chỉ. Chủ đề an toàn có thể được hạt mịn bên trong phương pháp.

9

Không được ghi đè phương thức "đồng bộ hóa" mà không đặt "đồng bộ".

Sai. Lớp cơ sở có thể không an toàn với luồng, nhưng lớp con có thể có đồng bộ hóa riêng, chẳng hạn như khóa, cấu trúc dữ liệu an toàn không khóa, v.v. Không phải tất cả các phương thức an toàn chỉ được đồng bộ hóa, chứ không phải tất cả các phương thức đồng bộ an toàn chỉ.

Cùng có thể đi theo một hướng khác (nhưng có thể phá vỡ các nguyên tắc khác, tùy từng trường hợp)

synchronized không phải là một điều hướng đối tượng, mà là một hiện tượng thời gian chạy/thực hiện, và một thực hiện chi tiết. Tất cả nó là acquire a monitor cùng một cách synchronized(this){ } (hoặc đồng bộ hóa trên đối tượng java.lang.Class nếu tĩnh). Như là một chi tiết thực hiện, nó không có ý nghĩa để lộ nó để OOP cân nhắc.

Lưu ý: Điều này không có nghĩa là chú thích biên dịch theo thời gian như @ThreadSafe không có ý nghĩa. Nó có, vì nó tham chiếu đến hợp đồng của phương thức để an toàn luồng. synchronized không thực hiện việc này.

+0

Không được ghi đè phương thức "đồng bộ hóa" mà không đặt "đồng bộ". Tôi hỏi rằng tại sao nó không được thiết kế theo cách như vậy. Tôi không nói rằng nó hoạt động theo cách này. – Onki

+2

@ user3610891 Đó là những gì bạn đang nói trong câu hỏi ban đầu của bạn. Tôi giải thích rằng điều đó không đúng, vì đó là một phần quan trọng trong việc trả lời câu hỏi của bạn. Tôi – hexafraction

+0

vì vậy bạn đang nói rằng một phương pháp đồng bộ được chuyển đổi thành khối đồng bộ? – Onki

1

Hãy để tôi đặt nó một cách khác nhau:

Giả sử chúng ta có hai lớp:

class Foo { 
    public synchronized void doSomething(...) { ... } 
} 

class Bar extends Foo { 
    public void doSomething(...) { ... } 
} 

FooBarkhác nhau lớp. foo.doSomething(...)bar.doSomething(...) là các phương pháp khác nhau.

Từ khóa synchronized không có cho lợi ích của người gọi: Nó không nói gì về những gì foo.doSomething(...)không. Từ khóa synchronized chỉ là chi tiết về cách thức mà phương pháp đó được thực hiện được triển khai.

Lớp Foo cần phương thức doSomething(...) để được đồng bộ hóa để thực hiện chính xác hợp đồng API trong môi trường nhiều luồng. Phương pháp bar.doSomething(...) được triển khai khác và không cần đồng bộ hóa.

Vì vậy, miễn là phiên bản Bar có thể được sử dụng bất cứ khi nào một cá thể Foo được yêu cầu, mọi người sẽ vui vẻ. Không có lý do tại sao người gọi nên muốn phương thức được đồng bộ hóa: Người gọi chỉ muốn phương thức hoạt động.

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