本文主要根据《Java程序员修炼之道》整理的代码笔记片段
一个线程更新,备用线程确认更新 (Lock lock = new ReentrantLock(); boolean acquired = lock.tryLock(wait, TimeUnit.MILLISECONDS); //Java 5)
public interface ConfirmingMicroBlogNode {
void propagateUpdate(Update upd_, ConfirmingMicroBlogNode backup_);
boolean tryConfirmUpdate(ConfirmingMicroBlogNode other_, Update update_);
String getIdent();
}
public class FixedDeadlockWithLockMicroBlogNode implements
ConfirmingMicroBlogNode {
private static Update getUpdate(String s) {
Update.Builder b = new Update.Builder();
b.updateText(s).author(new Author("Ben"));
return b.build();
}
private final String ident;
private final Lock lock = new ReentrantLock();
public FixedDeadlockWithLockMicroBlogNode(String ident_) {
ident = ident_;
}
@Override
public String getIdent() {
return ident;
}
@Override
public void propagateUpdate(Update upd_, ConfirmingMicroBlogNode backup_) {
boolean acquired = false;
boolean done = false;
while (!done) {
int wait = (int) (Math.random() * 10);
try {
acquired = lock.tryLock(wait, TimeUnit.MILLISECONDS);
if (acquired) {
System.out.println(ident + ": recvd: " + upd_.getUpdateText()
+ " ; backup: " + backup_.getIdent());
done = backup_.tryConfirmUpdate(this, upd_);
}
} catch (InterruptedException e) {
} finally {
if (acquired)
lock.unlock();
}
if (!done)
try {
Thread.sleep(wait);
} catch (InterruptedException e) {
}
}
}
@Override
public boolean tryConfirmUpdate(ConfirmingMicroBlogNode other_, Update upd_) {
long startTime = System.currentTimeMillis();
boolean acquired = false;
try {
int wait = (int) (Math.random() * 10);
acquired = lock.tryLock(wait, TimeUnit.MILLISECONDS);
if (acquired) {
long elapsed = System.currentTimeMillis() - startTime;
System.out.println(ident + ": recvd confirm: " + upd_.getUpdateText()
+ " from " + other_.getIdent() + " - took " + elapsed + " millis");
return true;
}
} catch (InterruptedException e) {
} finally {
if (acquired)
lock.unlock();
}
return false;
}
public static void main(String[] a) {
final FixedDeadlockWithLockMicroBlogNode local = new FixedDeadlockWithLockMicroBlogNode(
"localhost:8888");
final FixedDeadlockWithLockMicroBlogNode other = new FixedDeadlockWithLockMicroBlogNode(
"localhost:8988");
final Update first = getUpdate("1");
final Update second = getUpdate("2");
new Thread(new Runnable() {
public void run() {
local.propagateUpdate(first, other);
}
}).start();
new Thread(new Runnable() {
public void run() {
other.propagateUpdate(second, local);
}
}).start();
}
}