2010-09-11 37 views
6

Tôi là chủ đề và đồng bộ Java mới.Câu hỏi được đồng bộ hóa Java

phép nói rằng tôi có:

public class MyClass(){ 

    public synchronized void method1(){ 
     //call method2(); 
    } 

    public synchronized void method2(){}; 

} 
  1. có nghĩa là gì khi tôi đồng bộ hóa một method1() vào một đối tượng dụ? Vì vậy, khi một sợi có được khóa khi cố truy cập vào synchronized method1(), nó có ngăn chặn các luồng khác truy cập một số synchronized method2() khác từ cùng một đối tượng đó không?

  2. Cho phép nói chuỗi tìm kiếm khóa khi truy cập phương thức1(), nhưng giả sử rằng method1() gọi điện đến method2() cũng là synchronized. Điều này có thể được không? Ý tôi là có bất kỳ quy tắc nào có thể ngăn chặn method1() gọi số method2()?

Xin cảm ơn trước.

Trả lời

4
  1. See here:

    nó không phải là có thể cho hai lời gọi của phương pháp đồng bộ trên cùng một đối tượng để interleave. Khi một luồng đang thực hiện một phương thức đồng bộ cho một đối tượng, tất cả các luồng khác gọi ra các phương thức đồng bộ cho cùng một khối đối tượng (tạm dừng thực hiện) cho đến khi luồng đầu tiên được thực hiện với đối tượng.

  2. Kể từ chủ đề này giữ chốt trên đối tượng hiện nay, nó có thể gọi method2(), và không có chủ đề khác có thể.

7
  1. Vâng, bằng cách sử dụng modifier synchronized phương pháp trên một phương pháp không tĩnh có nghĩa là nó sử dụng màn hình của trường hợp phương pháp này được gọi về, và điều này được chia sẻ giữa tất cả các phương pháp như vậy.
  2. Không - luồng đã sở hữu màn hình, do đó bạn có thể tự do nhập các khối khác được bảo vệ bởi cùng một màn hình.
2

Một lưu ý về câu hỏi 2, method1() cũng có thể gọi các phương thức đồng bộ cũng trong lớp khác mà có thể gây ra một bế tắc:

thread1 cuộc gọi đồng bộ method1() do đó cần gọi method_b đồng bộ() trong AnotherClass Thread2 giữ khóa trên AnotherClass và đang thực hiện một phương thức cần gọi phương thức1() trong lớp có khóa được giữ bởi Thread1

Cả hai Chủ đề sẽ chặn việc chờ khóa khác tự do khóa, bế tắc.

2

(1) Đây là tương đương với:

public void method1(){ 
    synchronized (this) { 
     ... 
    } 
} 

Vì vậy, nó đồng bộ hóa trên dụ hiện hành. Nếu chúng tôi viết lại method2 theo cùng một cách ...

public void method2(){ 
    synchronized (this) { 
     ... 
    } 
} 

...sau đó bạn có thể thấy rõ ràng rằng chúng khóa trên cùng một đối tượng và do đó các luồng khác không thể gọi method1 hoặc method2 cho đến khi method1 thoát khỏi khối synchronized của nó.

(2) synchronized khối được chuyển nhượng lại, có nghĩa là cùng một chuỗi có thể nhập các khối khác synchronized khóa trên cùng một đối tượng bao nhiêu lần tùy thích. Theo tôi hiểu, mỗi khi bạn nhập một khối synchronized, Java sẽ tăng bộ đếm đối tượng bạn đang đồng bộ hóa lên 1 và mỗi khi bạn thoát khỏi khối synchronized, nó sẽ giảm nó. Khi bộ đếm đó đạt tới 0, khóa sẽ được giải phóng.

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