2011-11-25 49 views
8

Trong đoạn mã dưới đây, khai báo phương thức doThings() là static sẽ làm cho lớp thread-safe. Có phải lý do cho điều này là nếu nhiều chuỗi TestSeven được bắt đầu và vì x là một biến tĩnh, một điều kiện chủng tộc có thể xảy ra?Tại sao mã này không phải là chuỗi an toàn?

public class TestSeven extends Thread{ 

    private static int x; 

    public synchronized void doThings(){ 
     int current = x; 
     current++; 
     x = current; 
    } 

    public void run(){ 
     doThings(); 
    } 

    public static void main(String args[]){ 
     TestSeven t = new TestSeven(); 
     Thread thread = new Thread(t); 
     thread.start(); 
    } 
} 
+1

Btw bạn vượt qua một TestSeven là một Chủ đề làm đối số cho hàm tạo Thread. Điều này làm việc vì Thread IS-A Runnable, nhưng không được khuyến khích, bạn nên làm cho TestSeven thực hiện Runnable –

Trả lời

15

Có, chính xác. Bản chất synchronized của doThings chỉ ngăn không cho nó được gọi bởi nhiều chủ đề đồng thời trên cùng một trường hợp. Biến số x được chia sẻ trên cơ sở toàn cầu, chứ không phải trên cơ sở từng trường hợp, do đó không an toàn.

Trong điều kiện thực tế, hãy nghĩ về nó như một phòng tắm có nhiều cửa - ai đó có thể mở một cánh cửa và khóa nó, nhưng điều đó không ngăn người khác đến qua một cánh cửa khác ...

+1

Ví dụ rất hay. – gprathour

+0

+1: khóa trên luồng hiện tại, đó là trường hợp ở đây, hầu như luôn vô nghĩa. –

+0

Giải thích rất tốt. Tóm tắt nhưng tóm tắt nó một cách độc đáo. –

1

Tôi nghĩ rằng nếu phương pháp này không tĩnh, mỗi đối tượng TestSeven sẽ đồng bộ hóa bằng khóa riêng của nó - vì vậy sẽ có một luồng cho mỗi khóa và không ai trong số đó sẽ phải chờ một chuỗi khác. Nếu phương thức được khai báo tĩnh, tôi dường như nhớ lại chúng khóa trên đối tượng Class tương ứng.

1

Chỉ cần thêm rằng nếu bạn khai báo phương thức doThings tĩnh, nó sẽ đồng bộ hóa trên khóa lớp chứ không phải khóa ví dụ để nó sẽ được chống đạn.

1

có. Điều kiện cuộc đua có thể xảy ra trong điều này. Vì bạn đang làm cho phương thức được đồng bộ hóa chứ không phải biến của bạn. Vì vậy, theo định nghĩa của điều kiện chủng tộc, một chủ đề sẽ đọc giá trị của biến trong khi khác trong phương pháp đồng bộ có thể viết nó. Vì vậy, một điều kiện chủng tộc sẽ có mặt ở đó.

1

Bạn đồng bộ hóa mã của mình trên this, có nghĩa là trên ví dụ đó của TestSeven. x là tĩnh, vì vậy nó sẽ không bị khóa. Đó là lý do tại sao, từ các trường hợp khác nhau, bạn có thể truy cập cùng một số x. Để mở khóa trên thuộc tính đó, bạn sẽ cần phải đồng bộ hóa trên lớp.

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