2012-05-13 44 views
12

xem xét đoạn mã sau:phương pháp Java hai đồng bộ trong một trường hợp

public class SynchronizedCounter extends Thread { 
    private int c = 0; 

    public synchronized void increment() { 
     c++; 
    } 

    public synchronized void decrement() { 
     c--; 
    } 

    public void run() { 
     for(;;) 
      increment(); 
    } 
} 

static void main(String[] args) { 
    SynchronizedCounter counter = new SynchronizedCounter(); 
    counter.start(); 
    for(;;) 
     counter.decrement(); 
} 

thực hiện điều này có nghĩa là increment()giảm một() phương pháp này sẽ chờ nhau để kết thúc hay không?

EDIT: và điều này không chờ đợi?

static void main(String[] args) { 
    SynchronizedCounter counter1 = new SynchronizedCounter(); 
    SynchronizedCounter counter2 = new SynchronizedCounter(); 
    counter1.start(); 
    for(;;) 
     counter2.decrement(); 
} 

Trả lời

13

Vâng, từ khóa synchronized là viết tắt của:

synchronized(this) { 
    //... 
} 

Vì vậy, cả hai phương pháp được khóa một cách hiệu quả trên đối tượng mutex cùng. Nếu bạn muốn chúng độc lập với nhau (đó là một ý tưởng tồi trong ví dụ này khi cả hai đều truy cập cùng một giá trị), hãy xem Object locking private class members - best practice? (Java).

BTW SynchronizedCounter của bạn nên triển khai Runnable thay vì mở rộng Thread vì bạn đang chuyển nó đến hàm tạo khác của chuỗi - bây giờ có chút khó hiểu.

+0

yeah, bạn là đúng về mở rộng Chủ đề, chỉ cần sửa mã :) – MBZ

6

Khóa luôn ở trên toàn bộ đối tượng. Nếu bất kỳ ai trong số đó là thành viên synchronized được truy cập.

Trong ví dụ đầu tiên của bạn, có hai luồng tranh cho cùng một đối tượngcounter, một trong những bạn bắt đầu một cách rõ ràng (trong đó kêu gọi các increment() phương pháp trong vòng lặp vô hạn) và các chủ đề khác là các chủ đề chính (trong đó kêu gọi các decrement() vô hạn).

Trong ví dụ thứ hai, có hai đối tượng được tạo counter1counter2. Chúng sẽ có khóa riêng của chúng độc lập với nhau. Khóa một đối tượng không ảnh hưởng đến các chủ đề khác truy cập vào đối tượng khác. Hai chủ đề (các chủ đề rõ ràng và chính) có được khóa trên hai đối tượng khác nhau và do đó có trong không có tranh chấp.

1

điều này có nghĩa là phương thức increment() và decrement() sẽ đợi nhau kết thúc hay không?

NO, điều đó có nghĩa là không có chủ đề nào khác có thể gọi tăng() và giảm() khi có một chuỗi trong đó. Để được hoàn thành, chủ đề khác không thể thực hiện bất kỳ phương pháp đồng bộ của trường hợp này/đối tượng

Bạn có thể gọi bất kỳ phương pháp đồng bộ khác từ một đồng bộ mà không cần khóa trên cùng một ví dụ/đối tượng

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