2009-03-09 13 views
16
class A { 
    public synchronized void myOneMethod() { 
     // ... 
    } 
} 

class B extends A { 
    public synchronized void myOtherMethod() { 
     // ... 
    } 
} 

// ... 

B myObject; 

// ... 

myObject.myOneMethod(); // acquires lock 
myObject.myOtherMethod(); // same lock? 

Làm thế nào tôi hiểu được mô hình đồng bộ hóa, tôi muốn nói rằng có, bởi vì khóa/màn hình được liên kết với cá thể myObject và không quan trọng phương thức được xác định ở đâu. Nhưng tôi có đúng không? Nếu không, tại sao? Nếu có, tại sao bạn chắc chắn, và tôi không? :-)Java: Một phương thức được đồng bộ hóa trong siêu lớp có cùng khóa như một trong lớp con, phải không?

Trả lời

12

Có, bạn nói đúng và bạn cũng đã nhận được giải thích. Không có gì nhiều để thêm.

Lưu ý rằng nếu các phương pháp là static, thì chúng sẽ đồng bộ hóa trên các đối tượng khác nhau, cụ thể là các lớp tương ứng (A và B).

EDIT: Tại sao tôi chắc chắn? Tôi không biết, tại sao bạn không chắc chắn? ;-) myObject chỉ là một đối tượng - không có bất kỳ sự phân biệt nào giữa các thuộc tính myObject đến từ lớp A và các thuộc tính đến từ lớp B. (Vâng, về mặt kỹ thuật bạn có thể sử dụng sự phản chiếu để tìm ra cái nào, phải là một số khác biệt, nhưng hãy quên đi sự phản chiếu ngay bây giờ. Đối với các hoạt động phổ biến trên đối tượng không có sự phân biệt.)

7

Có, đồng bộ hóa tương đương với đồng bộ hóa (điều này).

Để có nhiều precise:

Đối với một phương pháp học (tĩnh), khóa liên quan đến đối tượng Class cho các lớp học của phương pháp được sử dụng. Đối với một phương thức thể hiện, khóa được liên kết với điều này (đối tượng mà phương thức được gọi) được sử dụng.

+0

Ví dụ các phương pháp, có. –

1

Có. Java sử dụng "màn hình" để thực hiện đồng bộ hóa và các phương thức đồng bộ sử dụng cá thể đối tượng mà chúng được gọi là màn hình, điều này rõ ràng là giống nhau trong trường hợp này.

Lưu ý rằng điều này KHÔNG đúng cho các phương pháp tĩnh! Ở đó, thể hiện lớp của (tôi nghĩ) lớp khai báo được sử dụng, lớp này sẽ không giống nhau.

0

Có bạn là chính xác

Khi một thread đang thực hiện một phương pháp đồng bộ cho một đối tượng, tất cả các chủ đề khác mà gọi các phương pháp đồng bộ cho khối cùng một đối tượng (đình chỉ thực hiện) cho đến khi thread đầu tiên được thực hiện với các đối tượng. Trong trường hợp này đối tượng là B

3

Nếu bạn muốn trở thành rõ ràng hơn về khóa của bạn, bạn có thể làm một cái gì đó như thế này:

class A { 

    protected final Object mutex = new Object(); 
    public void myOneMethod() { 
     synchronized (mutex) { 
      // ... 
     } 
    } 
} 

class B extends A { 
    public void myOtherMethod() { 
     synchronized (mutex) { 
      // ... 
     } 
    } 
} 

Trong thực tế, mô hình này được khuyến khích bởi Brian Goetz trong Java Concurrency trong Thực hành, phần 4.2.1 "Mẫu màn hình Java". Bằng cách đó bạn biết chính xác nơi màn hình của bạn đến từ đâu.

+0

Yup. Ngoài ra, đây là những gì Jon Skeet làm: http://stackoverflow.com/questions/609963/java-what-if-anything-is-locked-by-synchronized-methods-apart-from-the-object/609981#609981 ;) Tôi sẽ sử dụng mẫu đó, ngoại trừ những phương pháp mà nó thực sự có ý nghĩa nhất để khóa "điều này". –

+0

Cảm ơn bạn đã đề cập đến phương pháp này. Tuy nhiên, Q ban đầu có thể ám chỉ đến một lớp A đến từ một thư viện. Ít nhất, đó là lý do tại sao tôi tìm kiếm chủ đề. Trong trường hợp đó, có vẻ như các cân nhắc bổ sung được đưa vào chơi. –

0

Chỉ cần một bổ sung nhỏ cho những người có thể quan tâm trong thời gian tới ..

Thêm vào đó hãy nhớ rằng ổ khóa trong Java là lõm. Nếu họ không phải mã này của bạn sẽ dẫn đến bế tắc vì bạn đã chỉ ra cả hai thao tác đều yêu cầu cùng một khóa.

0

Từ quan điểm khái niệm, tính toàn vẹn mutex của một số trường hợp thừa kế sẽ bị hỏng nếu synchonized phương thức của lớp A sẽ chỉ bảo vệ dữ liệu của A trong ngữ cảnh của lớp con B. Xét cho cùng, không phải tất cả dữ liệu của A là bắt buộc phải là private.

Hãy tưởng tượng rằng bạn muốn mở rộng một chút chức năng của một phương thức A trong khi vẫn giữ các chức năng còn lại của A bao gồm cả bảo vệ mutex. Nếu A chỉ bảo vệ chính nó, bạn sẽ phải ghi đè lên tất cả các phương thức tất cả của A 'synchronized để nâng cơ chế đồng bộ hóa ban đầu lên lớp con mới. Không phải là rất hấp dẫn và cũng không phải là rất hiệu quả.

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