Each object's lock is little different from Mutex/Semaphore design. For example there is no way to correctly implement traversing linked nodes with releasing previous node's lock and capturing next one. But with mutex it is easy to implement:
Node p = getHead();
if (p == null || x == null) return false;
p.lock.acquire(); // Prime loop by acquiring first lock.
// If above acquire fails due to interrupt, the method will
// throw InterruptedException now, so there is no need for
// further cleanup.
for (;;) {
Node nextp = null;
boolean found;
try {
found = x.equals(p.item);
if (!found) {
nextp = p.next;
if (nextp != null) {
try { // Acquire next lock
// while still holding current
nextp.lock.acquire();
}
catch (InterruptedException ie) {
throw ie; // Note that finally clause will
// execute before the throw
}
}
}
}finally { // release old lock regardless of outcome
p.lock.release();
}
Currently, there is no such class in java.util.concurrent
, but you can find Mutext implementation here Mutex.java. As for standard libraries, Semaphore provides all this functionality and much more.