2011-06-22 25 views
8

Tôi cố gắng để đồng bộ hóa trên một đối tượng trong mã của tôi dưới đây:NullPointerException trên tuyên bố đồng bộ

public void myMethod() { 
    synchronized (globalObj) { 
     //Do something here 
    } 
} 

Mã này được thực hiện trong một thread. Vấn đề là, một chủ đề khác có thể đặt 'globalObj' thành null. Sau đó, 'sync (globalObj)' sẽ ném NullPointerxception khi 'globalObj' được đặt thành null bởi các luồng khác.

Thực tiễn tốt nhất để đồng bộ hóa trên một đối tượng để NullPointerException sẽ không bị ném là gì?

Cảm ơn.

+0

Vui lòng nhập mã. –

Trả lời

25

Bạn không nên đồng bộ hóa trên tham chiếu mà chính nó có thể bị thay đổi. Nếu một chuỗi khác được phép thay thế globalObj, điều đó có nghĩa là bạn có thể giữ khóa cho số globalObj cũ trong khi một luồng khác hoạt động trên một luồng hoàn toàn khác - khóa không giúp gì cho bạn.

Bạn nên làm gì thay vào đó là có một riêng biệt Object cho mục đích này:

static final Object lockObj = new Object(); 

public void myMethod() { 
    synchronized (lockObj) { 
    // do something with globalObj here 
    } 
} 

Kể từ lockObj bao giờ thay đổi, bạn sẽ luôn sử dụng cùng một khóa - không có vấn đề.

1

Hãy chắc chắn rằng bạn đồng bộ hóa trên một đối tượng mà không thể được null ...

Tại sao các bạn cách thiết lập các globalObj null? Điều gì sẽ là ngữ nghĩa đồng thời cho điều này? Có phải ngẫu nhiên không?

Nếu cần thiết phải khóa đi đôi khi (có vẻ lạ), bạn có thể thêm một kiểm tra rỗng (tất nhiên, bạn sẽ cần phải đồng bộ hóa trên một thứ khác để tránh tình trạng cuộc đua kiểm tra đầu tiên cho null, và sau đó có nó được đặt thành null ngay sau đó).

Vui lòng mô tả kịch bản của bạn chi tiết hơn.

0

Tạo thành viên nhóm đối tượng riêng tư không có bất kỳ người định cư công khai nào và khóa trên đó.

6

Bạn không thể đồng bộ hóa trên tham chiếu null. Cách tốt nhất là đồng bộ hóa đối tượng final (để đảm bảo rằng nó không bao giờ là null), hoặc (tốt hơn) sử dụng các trừu tượng đồng thời ở mức cao hơn trong gói java.util.concurrent.