2013-02-18 35 views
17

Ví dụ, điều này có tốt hơn không?Tốt hơn là nên có khối đồng bộ bên trong khối thử hoặc khối thử bên trong khối được đồng bộ hóa?

try { 
    synchronized (bean) { 
     // Write something    
    } 
} catch (InterruptedException e) { 
    // Write something 
} 

Hoặc nó tốt hơn này:

synchronized (bean) { 
    try {   
     // Write something    
    } 
    catch (InterruptedException e) { 
     // Write something 
    } 
} 

tôi đã tự hỏi cái nào là thực hành tốt nhất. Rõ ràng là tôi phải đồng bộ hóa tất cả các mã bên trong khối thử. Tôi không nói về trường hợp tôi đã đồng bộ hóa chỉ một phần của mã bên trong thử (trong trường hợp này tôi nghĩ rằng nó sẽ là tốt hơn để có khối đồng bộ bên trong thử). Nghi ngờ của tôi là về trường hợp tôi đã đồng bộ hóa tất cả khối thử.

Trả lời

11

Tốt hơn nên có khối đồng bộ bên trong khối thử hoặc khối thử bên trong khối được đồng bộ hóa?

Trừ khi bạn cần một cách rõ ràng catch là trong khối synchronized, tôi sẽ làm phần synchronized mã càng nhỏ càng tốt và có nó bên trong try/catch. Vì vậy, mô hình đầu tiên sẽ tốt hơn. Sau đó, nếu bạn cần phải thực hiện các thao tác trong phần catch (như đăng nhập ngoại lệ hoặc ngắt lại luồng, xem bên dưới), chúng sẽ không chặn các luồng khác.

Điều đó nói rằng, nếu khối synchronized chứa một số dòng (thường không phải là một ý tưởng tốt tất nhiên) sau đó tôi sẽ xem xét di chuyển các khối try/catch gần gũi hơn với các phương pháp mà ném ngoại lệ (prolly wait hoặc notify). Với một số lượng lớn các dòng, bạn có nguy cơ xử lý không đúng các ngoại lệ với các khối try/catch lớn. Phụ thuộc một chút vào khung tham chiếu ở đây.

Là một sang một bên, hãy đảm bảo rằng bạn ít nhất đăng nhập ngoại lệ bị gián đoạn. Không bao giờ bỏ qua chúng. Bạn cũng có thể muốn ngắt lại chuỗi:

try { 
    ... 
} catch (InterruptedException e) { 
    // always a good pattern 
    Thread.currentThread().interrupt(); 
    // handle the interrupt here by logging or returning or ... 
} 
+0

'Sau đó, nếu bạn cần phải thực hiện các thao tác trong phần bắt ... những thứ này sẽ không chặn các chuỗi khác.' Tại sao chúng ta sẽ từ bỏ khóa do một ngoại lệ? – Cratylus

+0

Giống như @Gray cho biết, bạn phải chọn theo hiệu ứng bạn muốn, để đồng bộ hóa hành động của khối catch hoặc không, và để có khối đồng bộ nhỏ nhất có thể. Nhưng, tôi nghĩ bạn phải xem xét để giữ khối try/catch xung quanh mã bạn thực sự muốn bảo vệ, tránh các khối lớn hơn, nói rằng, chúng ta có thể tóm tắt hai cách lập trình tốt: 1. Giữ các khối được đồng bộ hóa nhỏ 2. Keep thử/bắt khối xung quanh mã bạn thực sự muốn bảo vệ. –

+0

"Tại sao chúng ta từ bỏ khóa do một ngoại lệ". Bởi vì các cuộc gọi đăng nhập có thể được đồng bộ và đắt tiền? Nó phụ thuộc vào mã nằm trong khối 'catch' @Cratylus. – Gray

0

Có vấn đề gì nếu khối catch của bạn được đồng bộ hóa? Vì bạn đã có "viết một cái gì đó" ở đó, tôi giả sử bạn sẽ làm một số việc ghi nhật ký mà không cần phải được đồng bộ hóa với một khung khai thác tốt, có nghĩa là câu trả lời có lẽ là no.

Nói chung, mục tiêu của bạn nên sử dụng đồng bộ hóa ít nhất có thể. Nhỏ hơn đồng bộ hóa của bạn chặn ít khả năng bạn gặp phải vấn đề.

3

Không có phương pháp hay nhất. Nó chỉ phụ thuộc nếu bạn cần một phần xử lý ngoại lệ bên trong khối được đồng bộ hóa hay không. Bạn có thể muốn một hoặc cái khác, và nên chọn một trong đó làm cho khối đồng bộ ngắn nhất, trong khi vẫn làm cho mã chính xác và an toàn thread.

0

Trong trường hợp này, InterruptedException có thể xảy ra chỉ trong synchronized khối, nơi bạn có thể hoặc gọi wait hoặc sleep hoặc notify.

Nói chung, cách tốt nhất là đặt khối try/catch gần mã có thể ném ngoại lệ để dễ xác định mã cần sửa.

0

Không có gì để làm với synchronized{try{}} hoặc try{synchronized{}}, nhưng mọi thứ phải làm với synchronized{catch{}} hoặc synchronized{} catch{}.Nó thực sự phụ thuộc vào những gì bạn làm trong khối catch.

Tuy nhiên, hãy dự đoán, đối với InterruptedException, bạn thường phải làm catch{} bên ngoài synchronized{}.

2

Bạn có vẻ nghĩ đây chỉ là một câu hỏi thẩm mỹ. Nó không phải là. Đó là một câu hỏi chức năng và câu trả lời được quyết định bởi yêu cầu trong từng trường hợp riêng biệt. Mỗi khối được đồng bộ phải lớn đến mức cần thiết để chứa bất kỳ thứ gì cần được đồng bộ hóa và không được lớn hơn.

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