Khi tôi chạy lớp mẫu tại http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html, tôi thấy hành vi tương tự như với synchronized
.bất cứ ai có thể giải thích cách sử dụng Khóa Reentrant trong java qua Đồng bộ hóa với một số ví dụ tốt nhất
Trả lời
Không, bạn thường sẽ không thấy sự khác biệt về hành vi. Nhưng theo trang web, có một vài trường hợp bạn sẽ muốn sử dụng một số ReentrantLock
thay vì synchronized
.
- Bạn muốn chủ đề chờ được chọn khá.
- Bạn muốn sử dụng phương thức tryLock().
- Bạn muốn làm gián đoạn một chuỗi đang chờ và yêu cầu làm điều gì đó khác.
- Hiệu suất của ReentrantLock tốt hơn so với đồng bộ hóa và bạn quan tâm đến điều đó.
Nếu bạn không cần bất kỳ cải tiến nào, sử dụng synchronized
là tốt và bạn không thể nói sự khác biệt.
Từ the JavaDoc of the ReetrantLock class:
Một reentrant loại trừ lẫn nhau
Lock
với hành vi cơ bản giống nhau và ngữ nghĩa như khóa màn hình ngầm truy cập dùngsynchronized
phương pháp và tuyên bố, nhưng với khả năng mở rộng.
Trong ví dụ của bạn, bạn không sử dụng "khả năng mở rộng"; bạn sử dụng phương thức ReentrantLock
làm phương án tương đương với phương pháp synchronized
(ngoại trừ câu lệnh synchronized
, bạn sử dụng this
làm khóa). Vì vậy, hai phương pháp phải hành xử giống nhau.
Dưới đây là ba cách, phương pháp, của chuỗi truy cập khóa và một phương pháp để bỏ khóa. Bạn có thể muốn thử triển khai các từ khóa này bằng cách sử dụng từ khóa synchronized
. Các khả năng mở rộng và lợi thế của việc sử dụng ReentrantLock
sẽ trở nên rõ ràng.
public class DoorLockUsingLock {
private int counter= 0;
private Thread owner= null;
private Lock l = new ReentrantLock();
private Condition notLocked= l.newCondition();
public void lockItDown() throws InterruptedException {
l.lockInterruptibly();
try {
while ((counter> 0) && (owner!= Thread.currentThread())) {
notLocked.await();
}
counter++;
owner = Thread.currentThread();
} finally {
l.unlock();
}
}
public void lockItDownUninterruptibly() {
l.lock();
try {
while ((counter > 0) && (owner != Thread.currentThread())) {
notLocked.awaitUninterruptibly();
}
counter++;
owner= Thread.currentThread();
} finally {
l.unlock();
}
}
public boolean tryLockItDown(long timeout, TimeUnit unit) throws InterruptedException {
long time = unit.toNanos(timeout);
long end = System.nanoTime() + time;
boolean success = l.tryLock(timeout, unit);
if (!success) {
return false;
}
try {
time = end- System.nanoTime();
while ((counter> 0) && (owner != Thread.currentThread()) && (time > 0)) {
notLocked.await(time, TimeUnit.NANOSECONDS);
time = end - System.nanoTime();
}
if (time > 0) {
counter++;
owner = Thread.currentThread();
return true;
}
return false;
} finally {
l.unlock();
}
}
public void unlockIt() throws IllegalMonitorStateException {
l.lock();
try {
if (counter== 0) {
throw new IllegalMonitorStateException();
}
if (owner!= Thread.currentThread()) {
throw new IllegalMonitorStateException();
}
counter--;
if (counter == 0) {
owner = null;
notLocked.signal();
}
} finally {
l.unlock();
}
}
}
Điều này về cơ bản tái tạo '' 'sync''',' '' wait''', và '' 'notify''' hành vi. '' 'ReentrantLock''' và' '' Condition''' làm sạch các ngữ nghĩa và cho phép sự công bằng, nhưng nếu không thì hầu như giống nhau. –
Điều này và có '' 'ReentrantReadWriteLock''' có thể hữu ích. Điều đó sẽ gây khó chịu khi thực hiện với '' 'sync'''. –