reentrancy có nghĩa là ổ khóa được mua trên một sợi mỗi chứ không phải là cơ sở cho mỗi sự thỉnh nguyện.
Đó là định nghĩa gây hiểu lầm. Nó là đúng (loại), nhưng nó bỏ lỡ điểm thực.
Reentrancy có nghĩa là (nói chung thuật ngữ CS/IT) bạn làm điều gì đó, và trong khi bạn vẫn đang làm điều đó, bạn làm điều đó một lần nữa. Trong trường hợp ổ khóa nó có nghĩa là bạn làm điều gì đó như này trên một chủ đề duy nhất:
- Thu lấy chốt trên "foo".
- Làm điều gì đó
- Nhận khóa trên "foo". Lưu ý rằng chúng tôi đã không phát hành khóa mà chúng tôi đã mua trước đó.
- ...
- khóa phát hành vào "foo"
- ...
- khóa phát hành vào "foo"
Với một khóa reentrant/khóa cơ chế, nỗ lực để có được giống nhau khóa sẽ thành công, và sẽ tăng một bộ đếm nội bộ thuộc về khóa. Khóa sẽ chỉ được giải phóng khi người giữ khóa hiện tại đã nhả ra hai lần.
Dưới đây là một ví dụ trong Java sử dụng nguyên thủy ổ khóa đối tượng/màn hình ... mà là reentrant:
Object lock = new Object();
...
synchronized (lock) {
...
doSomething(lock, ...)
...
}
public void doSomething(Object lock, ...) {
synchronized (lock) {
...
}
}
Các thay thế cho reentrant là khóa không reentrant, nơi mà nó sẽ là một lỗi cho một thread để cố gắng để có được một khóa mà nó đã nắm giữ.
Lợi thế của việc sử dụng khóa reentrant là bạn không phải lo lắng về khả năng thất bại do vô tình có được một khóa mà bạn đã giữ. Nhược điểm là bạn không thể giả định rằng không có gì bạn gọi sẽ thay đổi trạng thái của các biến khóa được thiết kế để bảo vệ. Tuy nhiên, đó không phải là vấn đề thường gặp.Khóa thường được sử dụng để bảo vệ chống lại các thay đổi trạng thái đồng thời được thực hiện bởi các chủ đề khác.
Vì vậy, tôi không cần xem xét sự bế tắc?
Có bạn đã làm.
Chủ đề sẽ không bế tắc đối với chính nó (nếu khóa là reentrant). Tuy nhiên, bạn có thể bị bế tắc nếu có các luồng khác có thể có khóa trên đối tượng bạn đang cố khóa.
Nguồn
2013-05-12 04:40:37
Hãy tưởng tượng nếu bước vào một phương pháp khóa đối tượng X, và trong khi ở phương pháp mà bạn gọi phương thức rất giống nhau (hoặc trực tiếp hoặc thêm vào trong cuộc gọi stack) và khóa đối tượng X một lần nữa. Chuyện gì xảy ra?Bạn có chờ đợi trên khóa bạn đã giữ, hoặc là nó nhận thức được rằng thread giữ nó cũng là thread gọi nó một lần nữa, và cho phép nó để vượt qua? Điều này được gọi là ủy nhiệm lại - bạn nhập cùng một phương thức mà bạn đã có trước đó. – Patashu
Có, các khối và khóa được đồng bộ hóa trong Java được cấp lại, vì vậy khi chuỗi foo có khóa, nó có thể gọi một cách an toàn các phương thức cũng khóa thanh mà không phải mở khóa trước. – Patashu
Bạn vẫn phải xem xét bế tắc, bế tắc có thể xảy ra khi hai luồng chờ nhau. – rubixibuc