2015-06-12 14 views
5

Tôi có một thread an toàn container lớp:Java kết hợp ổ khóa rõ ràng với các phương pháp đồng bộ

public class Container { 
    private int x; 
    ... 
    public synchronized int getX(); 
    public synchronized void setX(int x); 
} 

Sau đó, tôi có một danh sách container:

List<Container> containers; 

Tôi muốn lặp qua danh sách, aquire khóa của thùng chứa tại mỗi lần lặp và chỉ ở cuối vòng lặp, giải phóng tất cả các khóa. Something như thế này:

for(Container c : containers) { 
    c.lock(); 
    //do stuff 
} 
for(Container c : containers) 
    c.unlock(); 

tôi vẫn muốn đề khác để có thể tiếp tục sử dụng GetX và setX phương pháp container mở khóa, nhưng vì nhiều lý do tôi không muốn để cho phép điều đó cho container đã phân tích.

Bạn có biết mã java cho điều đó không?

Ý tưởng hay hơn cũng được đánh giá cao.

+0

Làm thế nào về việc có 'khóa() 'và' unlock() 'đầu tiên và cuối cùng trong' getX' và' setX'? – aioobe

+0

@see [ReentrantLock] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html) –

+0

@aioobe: Tôi muốn kết hợp các phương thức được đồng bộ hóa với ổ khóa (hy vọng rằng nó là possibile, nhưng tôi nghĩ rằng đó là bởi vì đằng sau hậu trường từ khóa đồng bộ mua lại khóa đối tượng). – Kami

Trả lời

1

Điều này là không thể tôi sợ. Ngôn ngữ Java áp đặt một nguyên tắc làm tổ chặt chẽ với các khối synchronized (...) { ... } (và các phương thức được đồng bộ hóa).

Điều đó đang được nói, có những cách giải quyết khó chịu. Trong bytecode khối được đồng bộ hóa thành hai hướng dẫn riêng biệt monitorenter/monitorexit. Điều tương tự cũng có thể đạt được với sun.mis.Unsafe.monitorEnter()monitorExit().

Tuy nhiên, trong trường hợp này, tôi thực sự khuyên bạn nên suy nghĩ lại về thiết kế. Tôi khuyên bạn nên để getXsetX có được/giải phóng nội bộ Lock (phương pháp truyền tải cũng sử dụng). Cụ thể, bạn có thể sử dụng ReadWriteLock cho các phương thức setXgetX của mình. Trong thực tế, cách tiếp cận này là tốt hơn so với phương pháp synchronized vì các lý do khác nữa. Xem ví dụ:

Why is it a good practice to have separate locks instead of having lock on object that get modified in the synchronized block in java?

+0

Từ khóa không đồng bộ có lấy khóa của đối tượng không? Nó giống như viết đồng bộ (this) {} bên trong phương thức. Nếu chúng tôi đang khóa về điều này, tại sao chúng ta không thể tạo ra một khóa khóa đối tượng (điều này)? – Kami

+0

Với khóa bên trong, tôi có gặp vấn đề tương tự không? Làm thế nào tôi có thể có được nhiều ổ khóa nội bộ (một tại mỗi lần lặp) mà không sử dụng từ khoá được đồng bộ hóa? – Kami

+0

Hiểu biết của bạn là chính xác. Lý do duy nhất chúng ta không thể làm một cái gì đó như 'lock (this);' và sau đó 'mở khóa (this);' (tương ứng với dấu ngoặc mở '{' resp.đóng ngoặc nhọn '}' của 'đồng bộ hóa (this)') là cách duy nhất để có được kiểu khóa này là thông qua từ khóa được đồng bộ hóa (trừ khi bạn sử dụng các hoạt động không an toàn như tôi đã đề cập trong câu trả lời của tôi) ràng buộc cú pháp của một khối '{...}'. – aioobe

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